Observable is not saving the data when refreshing

2019-07-31 15:27发布

问题:

I have this code in my service constructor:

this.getUser().subscribe( data => this.user = data.text(), error => console.log(error) );

When navigating in my app with router links (from menu) this code works, but when refreshing the page manually... data.text() includes the logged-in user (I can see it if I print it to console) but this.user variable is not saving it and it remains "undefined"!

I tried so far using a setTimeout or a BehaviorSubject but with no luck:

private _subject = new BehaviorSubject<any>([]);
subject$ = this._subject.asObservable();
this.getUser().subscribe( data => 
        //setTimeout(() => { this.user = data.text() }, 1000),
          this.user = this._subject.next(data),
                error => console.log(error) );

Update:

app.component.ts

import { Component, ViewEncapsulation, Output, EventEmitter } from '@angular/core';
import { ResourcesService } from './services/resources.service';
import { PrivilegeService } from './services/privilege.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
user: string;
constructor(
        private resourcesService: ResourcesService,
        private privilegeService: PrivilegeService
        ) { 

    if (Config.PROD_MODE)
        resourcesService.getUser().subscribe( data => {
            this.user = data.text(); 
            resourcesService.user = data.text();
        }, error => {console.log(error);

resource.service.ts :

  constructor(public http: Http){ 
  this.headers = new Headers({ 'Content-Type': 'application/json', 'Accept': 'application/json' });
  this.options = new RequestOptions({ headers: this.headers});}


/**
 * Get current user
 */
getUser(){
    let url = this.url + "user";  

    return this.http.get(url)
        //.catch( (error: any) => { console.log(error); return Observable.empty<Response>();} );
        .catch( (error: any) => Observable.throw(error || 'Server Error - could not get user') );
}

privilege.service.ts:

@Injectable()
export class PrivilegeService extends ResourcesService {
constructor(public http: Http){ 

  super(http);

  this.user = '';

resource-list.component:

public constructor(private resourcesService: ResourcesService,
                    private privilegeService: PrivilegeService, 
                    private router: Router, private route: ActivatedRoute) {

    if (Utils.isEmpty(this.resourcesService.user)){
        this.resourcesService.getUser().subscribe( data => {
            this.resourcesService.user = data.text();
            this.callGetResources();
        }, error => console.log(error) );
    }
}

I tried moving the call of get resources inside the observable block now I'm getting:

ERROR Error: InvalidPipeArgument: '' for pipe 'AsyncPipe' at invalidPipeArgumentError (common.es5.js:2610) at AsyncPipe.webpackJsonp.../../../common/@angular/common.es5.js.AsyncPipe._selectStrategy (common.es5.js:2755)

I realized that the call to getResources() is performed before setting the user variable of resources.service:

  1. in app.component the call to getUser() is performed, but data is still not ready. while debuging I can see data as follow:

message : "Unexpected end of input" stack : "SyntaxError: Unexpected end of input↵ at new AppComponent (http://localhost:8080/DataFabResourceManager/dist/main.bundle.js:247:9)↵

  1. then the call to getResources() is performed from the resources-list page (the one I'm standing on when refreshing). But the user is still undefined at this point

  2. back to app.component, now the data is ready and the user variable of resource service is sat (but too late):

200 statusText : "OK" type : 2 url : "http://localhost:8080/DataFabResourceManager/management/user" _body : "regressiontester_db" proto

回答1:

Try to do following:

in your service create function which would return observable:

getUser() {
    return http.get('here your rest api link to back-end');
}

And then call that method from your component, for example from ngOnInit() method. (You may follow by oficial guide from angular.io ):

ngOnInit() {
    this.service.getUser().subscribe('here your subscribe logic'); 
}

Also provide HttpClient to your service as constructor param. And then provide your service into component via constructor as well.

Helpful links:

https://angular.io/guide/dependency-injection

https://angular.io/guide/dependency-injection-pattern

http: https://angular.io/api/common/http/HttpClient