2

How can I make two service calls in the OnInit() method of the component ?

export class ApartmentComponent implements OnInit {
    public apartments: Object[];
    public temp: Object[];

    constructor(private apartmentService: ApartmentService) {
    this.apartmentService = apartmentService;
    }

    ngOnInit() {
    this.apartmentService.getApartments().subscribe(res => this.apartments = res);

    this.apartmentService.getStats().subscribe(res => this.temp = res);

    console.log(JSON.stringify(this.temp));
    }
}

In service.ts

getApartments() {
    return this.http.get('./api/businessunits/butype').map((res: Response) => res.json());
}

getStats(){ 
    console.log('Request reached');
    return this.http.get('./api/apartments/getstats').map((res: Response) => res.json());
} 

in server.ts (ExpressJS)

router.route('/api/businessunits/butype')             
.get(function(req, res) {
    BusinessUnit.find({unitID: {$exists: true}, UnitType: {$exists:  true}},'unitID UnitType',{sort:{unitID: 1}},function(err, businessunits) {
        if (err)
            res.send(err);

        res.json(businessunits);
     });
});

router.route('/api/apartments/getstats')             
.get(function(req, res) {
    //Apartment.aggregate([{$match:{_id: "aptType"}},{$group:{_id:{aptType:"$aptType"},count:{$sum:1}}}],function(err, apartments) {
      Apartment.find('aptType',function(err, apartments) {
        if (err)
            res.send(err);
        res.json(apartments);
     });
}); 

The getApartments() works fine individually when I comment out getStats() method call.

I am getting the following error

Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (M:\workspace\Angular2StartKit\node_modules\express
user2180794
  • 1,425
  • 7
  • 27
  • 50

1 Answers1

0

Subscribing to observables is an async operation, that means this just schedules a tasks to be done later.

When console.log(JSON.stringify(this.temp) is executed, the call to the server in getStats() (if it actually makes one - I just assume it does) wasn't even sent, and therefor definitely no response received yet.

It is also not clear from the code in your question whether the request for getApartments() or getStats() is sent first.

To preserve a specific order in async operations, you need to chain them properly so that the next is executed when the former is completed.

If you just want to print the result of getStats() this can be done like

ngOnInit() {
  this.apartmentService.getApartments().subscribe(res => this.apartments = res);

  this.apartmentService.getStats().subscribe(res => {
    this.temp = res;
    JSON.stringify(this.temp)
  });
}

alternatives are

ngOnInit() {
  this.apartmentService.getApartments().subscribe(res => this.apartments = res);

  this.apartmentService.getStats()
  .map(res => this.temp = res);
  .subscribe(temp => console.log(JSON.stringify(this.temp));
  });
}

or

ngOnInit() {
  this.apartmentService.getApartments().subscribe(res => this.apartments = res);

  this.apartmentService.getStats()
  .map(res => this.temp = res);
  .toPromise().then(temp => console.log(JSON.stringify(this.temp));
  });
}

If you want to chain 2 subscribes

this.apartmentService.getApartments().subscribe(res => this.apartments = res);
this.apartmentService.getStats().subscribe(res => this.temp = res);

there are lots of possiblilities like flatMap() depending on your requirements. You might want that they are sent one after the other is completed, or send both as soon as possible but then wait for both to complete. There are different ways to handle errors, ...

For more details see http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567