-1

I have created an Angular service which returns an Observable array of objects, using of from rxjs:

export class HackfestService {

  constructor(private http: HttpClient) { }

  getHackfests():Observable<HackFestDetails[]>{
    return of([
      {hackfestId: 1, hackfestName: "Hackfest Alpha",hackfestDate: new Date('June 12, 2018'), noOfParticipants: 500, noClearedPre: 100, isFinalResultOut:true, isPreResultOut:true},
      {hackfestId: 2, hackfestName: "Hackfest Beta",hackfestDate: new Date('July 22, 2018'), noOfParticipants: 0, noClearedPre:0 , isFinalResultOut:false, isPreResultOut:false}
    ]);
  }
}

It works fine until i replace the of part with an actual HttpClient.get() request like this:

export class HackfestService {

  private hackfestsURL =  'http://localhost:57161/api/Hackfest/GetHackfests';
  constructor(private http: HttpClient) { }

  getHackfests():Observable<HackFestDetails[]>{
    // return of([
    //   {hackfestId: 1, hackfestName: "Hackfest Alpha",hackfestDate: new Date('June 12, 2018'), noOfParticipants: 500, noClearedPre: 100, isFinalResultOut:true, isPreResultOut:true},
    //   {hackfestId: 2, hackfestName: "Hackfest Beta",hackfestDate: new Date('July 22, 2018'), noOfParticipants: 0, noClearedPre:0 , isFinalResultOut:false, isPreResultOut:false}
    // ]);
    return this.http.get<HackFestDetails[]>(this.hackfestsURL);
  }
}

I have tested the URL which gives the JSON result as:

    [{"hackfestId":1,"hackfestName":"Hackfest Alpha","hackfestDate":"2018-06-12T00:00:00","noOfParticipants":100,"noClearedPre":100,"isFinalResultOut":true,"isPreResultOut":true},
    {"hackfestId":2,"hackfestName":"Hackfest Beta","hackfestDate":"2018-07-22T00:00:00","noOfParticipants":0,"noClearedPre":0,"isFinalResultOut":false,"isPreResultOut":false}]

I have subscribed to the observable in my component as:

ngOnInit(){
    this.getHackfestList();
    this.selectedHackfest = this.allHackfests[0];
  }

  getHackfestList():void{
    //call api and get the list sorted in descending order of festival date
    this.hackfestService.getHackfests().subscribe(items => {
      this.allHackfests = items;
      console.log(this.allHackfests);
    });

    this.allHackfests.sort((x:HackFestDetails, y:HackFestDetails)=>{return y.hackfestDate.getTime()-x.hackfestDate.getTime()} );
  }

A console.log() inside the subscribe method actually logs the received JSON data from the HttpClient.get() method, but the attribute this.allHackfests remains undefined and hence gives errors when i try to access any of its attributes.

The official tutorial for Angular 6 had a similar implementation for which they state:

You've swapped of for http.get and the app keeps working without any other changes because both functions return an Observable

Clearly the statement is not consistent with what i observe in my implementation. Is there some more change that i might be missing?

1 Answers1

0

This is because getHackfests() is an asynchronous function.

The code will not wait and will execute the next lines, hence the error.

You should move the sort part inside the subscribe.

CornelC
  • 4,974
  • 1
  • 21
  • 28
  • But how does it work in case of call using Of ? It is also returning an observable. Also, it works fine in the official angular 6 tutorial. – Deepak Kumar Jul 10 '18 at 15:30