Have component execute function after service http.get call is finished

angular 4 synchronous http request
call a function after previous function is complete angular 6
angular after http request
angular 7 wait for http response
angular httpclient map response
angular 6 http get example
angularjs call function after another function
angular synchronous http

I'm having real trouble wrapping my head around observables and subscriptions in angular2. The problem I am currently having is the following:

I have a service which contains methods to post and get data from an API. The service is injected into a component, which directly calls those methods in the service. The service then retrieves data and stores it itself, but I then want to process that data within the component. I cannot work out how to have the component execute a function after the service has retrieved and stored the data itself.

service.ts

import { Injectable } from 'angular2/core';    
import { Http } from 'angular2/router';

@Injectable()
export class Service {
    result: Object;

    constructor(http: Http) {
        this.http = http;
    }

    httpGet(url) {
        return this.http.get(url).subscribe(
            result => this.result = result.json(),
            error => console.log(error),
            () => {}
        )
    }
}

component.ts

import { Component } from 'angular2/core';
import { Service } from './service';

@Component({
    ...
})
export class Component {
    formattedResult: Object;

    constructor(service: Service) {
        this.service = service;
        this.service.httpGet('/api')

        // How do I call format result on service.result only after it is completed?
        this.formatResult(service.result) // Need to execute this after the http call is completed

        // I want something like:
        this.service.httpGet('/api').then(() => formatResult(this.service.result));
    }

    formatResult(result) {
        this.formattedResult = result.map(x => x.length) // For example
    }
}

To answer my own question:

In the app root, import Rxjs with:

import 'rxjs/Rx';

This gives you access to the complete Observable object (not just the 'Observable-lite' included with Angular). This enables you to .map .reduce etc. the Http requests.

You can now use .map on an Http request to carry out arbitrary code in the context of the service, even if it is the component that subscribes to the result. So to achieve what I set out to do in the beginning, we can:

service.ts

import { Injectable } from 'angular2/core';    
import { Http } from 'angular2/router';

@Injectable()
export class Service {
    result: Object;

    constructor(http: Http) {
        this.http = http;
    }

    httpGet(url) {
        return this.http.get(url).map(
            result => {
                let data = result.json();
                this.result = data;
                return data
            }
        )
    }
}

component.ts

import { Component } from 'angular2/core';
import { Service } from './service';

@Component({
    // Component setup
})
export class Component {
    formattedResult: Object;

    constructor(service: Service) {
        this.service = service;
        this.service.httpGet('/api').subscribe(
            data => this.formatResult(data);
        );
    }

    formatResult(result) {
        this.formattedResult = result.map(x => x.length) // For example
    }
}

Thanks to Gunter and Mark for the replies, helped me wrap my head around this a bit and I feel like I understand Observables much better having gone through a lot of the docs solving this problem!

angular, To answer my own question: In the app root, import Rxjs with: import 'rxjs/Rx';. This gives you access to the complete Observable object (not just the  I passed this function as a prop to a child component. and when the child component triggers this function, it makes the API call, then this.setState is fired to re-render the state and show the update in the data.

Check if the result already arrived, if yes, create a new promise and complete it with the result, not not, fetch it, and return it as promise as well.

@Injectable()
export class Service {
    result: Object;

    constructor(http: Http) {
        this.http = http;
    }

    httpGet(url) {
        if(result === undefined) {
          return this.http.get(url).toPromise().then(
              result => this.result = result.json(),
              error => console.log(error);
          );
        } else {
          return new Promise().resolve(result);
        }
    }
}

I don't know TS and this code might contain some errors (I use Angular only Dart), but you should get the idea.

See also - http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

Angular 2: HTTP, Observables & Concurrent Data Loading, httpGet('/api') // How do I call format result on service.result only after it is completed? this.formatResult(service.result) // Need to execute this after the http call is  The service is injected into a component, which directly calls those methods in the service. The service then retrieves data and stores it itself, but I then want to process that data within the component. I cannot work out how to have the component execute a function after the service has retrieved and stored the data itself. service.ts

Well you could use a call back function in that case,

Taking example consider this is the post function which triggers the post service in service module

postData(id: string, name: string) {
    console.log("Got you",id);
  this._employeeService.postServices({id: id, name: name})
    .subscribe(
      (response:Response) => this.consoleMyOutput(),
      error => console.log(error)
    );  
}

Here note the function consoleMyOutput(). This will be triggered once the response is got after the service has been called

Now,

consoleMyOutput(){console.log("Write Your call back function")};

This function will be triggered just after that.

Sending a Request and Processing a Mapped Response to , demo.service'; import {Observable} from 'rxjs/Rx'; @Component({ selector: Just like Angular 1, we use http.get() to run our HTTP request. event handler executes after the Observable has finished returning all its data. You can use toPromise Function from rxjs and convert the http request to a promise then use async/await in your component to wait for result. Or you can use .then() and .catch() 45.4k views · View 9 Upvoters

It can happen simply with Rxjs methods , here is simple and classic way to call services once after application loaded then we can subscribe it into multiple components. Make sure services should be reusable for all component, so do much as u can do code in services and map, subscribe only in component :

Services:

 import { Injectable } from 'angular2/core';    
 import { Http } from 'angular2/http';

 @Injectable()
 export class Service {
     result: Object;

     constructor(private http: Http) {}

     private _urlGet = '/api';

     httpGet(){
        return this.http.get(this._urlGet)
          .map(res => JSON.parse(res.json()))
          .do(result => {
             this.result = result;
           }, error => console.log(error))
     }
  }

Component

 export class Component {
    formattedResult: Object;

    constructor(private service: Service) { }

    ngOnInit(){
       this.service.httpGet().subscribe(result => {
          this.formattedResult = result;
       }
    }
 }

Get data from a server, When we make a request to do something, they return a response Angular 7 is entirely based on components. We are using HttpClient to fetch data from the server to our After you've generated apicall.service.ts, import the HTTP client, and You can use the following command to run an Angular,. The trick here is to use the component internal setState. Every time you call setState, React will force the component to render again. So, suppose you have an asynchronous function getSomeData that will call a callback function when data is fetched from server. When this function is called, I set the state of the component with the data and the render function is called again.

48 answers on StackOverflow to the most popular Angular questions, Users can add, edit, and delete heroes and save these changes over HTTP. After installing the module, the app will make requests to and receive responses This particular HttpClient.get() call returns an Observable<Hero[]> ; that is, "an handler function to catchError that it has configured with both the name of the  The problem with this is that every single function inside the list gets executed at the same time. This works fine in some cases but if I want to create a more cinematic event I need to have the ability to execute a function after the previous one has finished it's execution .Sadly I have no idea how to do that.

HTTP Requests with Promises Example, How to pass url arguments (query string) to a HTTP request on ngOnInit is a lifecycle hook called by Angular2 to indicate that Angular is done creating the component. Implement this interface to execute custom initialization logic after I have the service in the bootstrap function so it has a provider. If you happen to run above code as it is, you would be getting the "Hi" alert first and then another alert coming from serverCall() service function. It is because when we click the button, serverCall() function from the service is called and without waiting for its response the next line executes and anotherFunctionCall() function is called.

AngularJS: API: $http, Angular 8/9 Promises Example – Manage HTTP Requests Promises in ECMAScript are very much identical to the promises we setTimeout(function() { resolve('Promise returns after 1.5 second!') Next, go to app.component.ts file. Here we will write the core logic to make the HTTP GET request and  After response.End() i want to execute another code. Call javascript function in btnDownLoad server side code and save the data to be downloaded into viewstate.

Comments
  • stackoverflow.com/questions/34739574/…
  • @GünterZöchbauer Thanks, its close but I wanted to keep a .subscribe in the service since it stores that information itself for later access. It isn't possible to have two .subscribes on one http.get (it will call it twice). Unless the accepted design pattern is to have .subscribe only in the components and explicitly set the service variables from the component? I wanted to keep the service and component logic separated is all.
  • stackoverflow.com/a/34405243/215945 - that answer chains observables using flatMap().
  • To include operators from rxjs create file rxjs-extensions.ts and include it in your polyfils, add imports for used operators as import 'rxjs/operator/map' etc. Also never import full lib as import 'rxjs/Rx' cause it is not needed. You can check what is included in your maps with source map explorers of different kind for webpack, angular, js
  • After lots of struggle. Finally its working for me, thanks man.
  • Ok, cool I can see how that works. Seems a bit of a shame to just convert it back to Promises so you can .then chain. I was hoping there was some new observable way of doing it that I just didn't know about. Oh well - thanks!
  • As I mentioned, I'm not a TS developer, but from other posts I have seen, it seems the way to go.