How to update a view when angular $ http promise a call wrapped in rxjs Observed

I have a project that uses the angular $ http service to download data from a remote location. I want to use rxjs Observables, so the call in my service is as follows:

    userInfo() : Rx.Observable<IUserInfo> {
        var url : string = someUrl + this._accessToken;

        return Rx.Observable.fromPromise<IUserInfo>( this.$http.get<IUserInfo>( url ) );
    }

and my subscriber subscribes as follows:

    getUserInfo() : void {
        this._googleService.userInfo().subscribe(
            ( result ) => { this.handleUserInfo( result ) },
            ( fault : string ) => this.handleError( fault )
        )
    }

    private handleUserInfo( result : IHttpPromiseCallbackArg<IUserInfo> ) : void {
        console.log( "User info received at " + new Date() );

        this._name = result.data.given_name + " " + result.data.family_name;
        this._email = result.data.email;

        this._profilePicUrl = result.data.picture;
    }

the problem is that although the update of the name, email and pic profile has been updated, these changes are not visible. As soon as something else starts angular $, the changes are applied, but due to the Observable, these changes in the controller occur after the angular digest loop, which is started by calling $ http. This works correctly if my service simply returns a promise to the controller.

? , . , Observables , .

+4
2

ScopeScheduler rx.angular.js . , angular $rootScope:

const module : ng.IModule = angular.module( 'moduleName', [] );

module.run( ["$rootScope", ( $rootScope ) => {
    new Rx.ScopeScheduler( $rootScope );
}]);

, . Rx.Observables $apply, .

- ScopeScheduler , rx.angular.js ​​ rxjs 4. rx.angular.js 0.0.14 ScopeScheduler.

, 4.

, , :

https://github.com/Roaders/Typescript-OAuth-SPA/tree/observable_apply_issues

+3

Rx.ScopeScheduler , rx- $rootScope. $apply:)

module.run(['$rootScope', 'rx', function ($rootScope, rx) {
    rx.Observable.prototype.subscribe = function (n, e, c) {
        if(typeof n === 'object') {
            return this._subscribe(n);
        }

        var onNext = function(){};
        if(n) {
            onNext = function(value) {
                if($rootScope.$$phase) {
                    n(value);
                }
                else {
                    $rootScope.$apply(function(){ n(value); });
                }
            };
        }

        var onError = function(err) { throw err; };
        if(e) {
            onError = function(error) {
                if($rootScope.$$phase) {
                    e(error);
                }
                else {
                    $rootScope.$apply(function(){ e(error); });
                }
            };
        }

        var onCompleted = function(){};
        if(c) {
            onCompleted = function() {
                if($rootScope.$$phase) {
                    c();
                }
                else {
                    $rootScope.$apply(function(){ c(); });
                }
            };
        }

        return this._subscribe(
            new rx.AnonymousObserver(onNext, onError, onCompleted)
        );
    };
}]);
0

Source: https://habr.com/ru/post/1622948/


All Articles