Can't assign value to variable using subscribe() method in Angular 2

前端 未结 3 541
无人共我
无人共我 2021-02-12 13:58

The promise returns a value but I don\'t seem to be assigning the value properly in the subscribe method.

import { Component } from \'@angular/core\';
import {          


        
相关标签:
3条回答
  • 2021-02-12 14:13

    component context "this" is not available inside of the subscribe(), to fix this, declare _this and assign this before the subscribe() as shown below;

        constructor (private dataService: DataService){
               const _this = this;
               dataService.getCompaniesCount().subscribe(res => {
                  this.companyCount = res.count; // does't work
               });
               dataService.getCompaniesCount().subscribe(res => { _this.companyCount = res.count; //works
            });
    }
    
    0 讨论(0)
  • 2021-02-12 14:16

    I understand that the thread is old. So, this for the new users who are trying now. I am not sure if this is something that you are looking for. But we can persist data in a component variable albeit an ugly workaround. Here is how we used in a sample POC

    (Please use the proper hooks as subsribing to an observable is not preferred in a constructor)

            @Component({
      selector: 'app-search-promo',
      templateUrl: './search-promo.component.html',
      styleUrls: ['./search-promo.component.css']
    })
    export class SearchPromoComponent implements  AfterViewInit {
      searchGroup: FormGroup;
      stringify  =  require('json-stringify-safe');
      someResult:any;
      resp:Response;
      localInput = new FormControl('', Validators.required);
      consumedPromoList: Observable<Promotion[]>;
      constructor(private searchService: SearchService, fb: FormBuilder) {
        this.searchGroup = fb.group({
          'localInput': this.localInput
        });
         this.stringify = require('json-stringify-safe');
         this.searchService.getPromoList().subscribe(
           resp => {
             this.someResult = <Promotion[]>resp;
             console.log("Inside sub in comp"+this.stringify(resp));
             console.log("before calling the methid");
             this.callDto(<Promotion[]>resp);
           }
         );
         console.log('inside const()' + this.stringify(this.someResult));
       }
    
    callDto(data){
        console.log("caling"+data);
        this.someResult = <Promotion[]>data;
        console.log("Now priting:"+this.someResult);
        this.anotherMethod();
      }
    
      anotherMethod(){
        console.log("Inside another method"+this.stringify(this.someResult));
      }
    }
    

    That was the sample component and below is the sample service

    @Injectable()
    export class SearchService {
      getUrl: String = './../assets/promotionList.json';
      subject: BehaviorSubject<Promotion[]> = new BehaviorSubject([]); // initialize with an empty response[]
      subjectAsObservable;
       someResult;
       promoList:Promotion[];
      constructor(private http: HttpClient) {
        this.getPromoList();
        console.log("after first");
        this.getPromoValues();
        console.log("after second call");
      }
    
        getPromoList(){
        // by default it emits a response of Json and hence Observabpe<PromotionList>
        // throws an error
        this.someResult = this.http.get(`${this.getUrl}`);
        console.log("before map"+<Observable<Promotion[]>> this.someResult);
        return (<Observable<Promotion[]>> this.someResult);
        //console.log("first subsriber"+JSON.stringify (this.someResult);
    
      }
    
    0 讨论(0)
  • 2021-02-12 14:27

    With this code

    export class TopbarComponent {
      companyCount;
    
      constructor (private dataService: DataService){
        dataService.getCompaniesCount().subscribe(res => this.companyCount = res.count); //doesn't work
        dataService.getCompaniesCount().subscribe(res => console.log(res.count)); //works    
      }
    }
    

    res => this.companyCount = res.count doesn't get executed immediately. When getCompaniesCount() makes a request to a server, it takes a long time until the response arrives and the observable calls the function passed to subscribe(...) (res => this.companyCount = res.count).

    The execution of the constructor, ngOnInit, ngAfterViewInit() and lots of other stuff will have happened before the response arrives.

    You can see

    subscribe(res => this.companyCount = res.count)
    

    like registering an event handler that gets called when an event happens.

    All code that depends on the data being available needs to be properly chained.

    The simplest way is to move to code into subscribe(...)

      constructor (private dataService: DataService){
        dataService.getCompaniesCount().subscribe(res => {
          this.companyCount = res.count); 
          // more code that depends on `res.count` being set goes here
        });
        dataService.getCompaniesCount().subscribe(res => console.log(res.count)); //works    
      }
    
    0 讨论(0)
提交回复
热议问题