-1

Hope you're doing well in this difficult time. Trust all is well in your end.

I am trying to make a local JSON call but after compiling the code, the json response which I am receiving is, is at the end of the execution of all the functions below. Here in the code, I am calling my loadService function in the app component. I don't want to import the JSON file in the head and use rather want to use the http service because I have to make serveral JSON calls based on conditions.

Function call in the App.component.ts

this.myservice.loadService();

The output is:

function 1

function 2

function 3

http response data

Expected:

http response data

function 1

... etc.

    import { Injectable } from '@angular/core';
    import { HttpClient, } from '@angular/common/http';
 
    @Injectable({
      providedIn: 'root'
    })
    export class InjectService {
    
        constructor(private http: HttpClient) {
            
          }
         loadService(){
         //logic 
         this.jsoncall()
         }
        
        jsonCall(){
            this.http.get("assets/abc.json").subscribe(data => {
            console.log(data);
            })
        }  
        function1(){
            console.log('function 1');            
            this.function2();
        }
    
        function2(){
            console.log('function 2')!
            this.function3();
        }
    
        function3(){
            console.log('function 3');   
        }
    }

Any help would be appreciated. Thank you. :)

Hitech Hitesh
  • 1,416
  • 1
  • 7
  • 15
jogo
  • 5
  • 4
  • How's function1 being called? – Ricardo Fornes Sep 20 '20 at 17:26
  • @RicardoFornes Thank you for your comment. You can assume jsonCall function. This is just a scenario that I have created for understanding. I am receiving the response at the end of everything which is not what I want. I want to have my data first then everything. – jogo Sep 20 '20 at 17:29
  • HTTP calls are asynchronous. The subscribe callback function will be executed once your HTTP request is resolved successfully. In this case, I assume the JSON file will always exist, so you might not need to cover the error/fail scenario. – Ricardo Fornes Sep 20 '20 at 17:34
  • If you need to react to the HTTP request failing scenario, you would so adding a second callback like this: `this.http.get("assets/abc.json").subscribe(data => { console.log(data); this.function1(); }, (error) => { console.log(error); })` – Ricardo Fornes Sep 20 '20 at 17:37
  • @RicardoFornes How then it will be available to me at the beginning of execution? First data response then other function executions – jogo Sep 20 '20 at 17:38
  • I think then that route resolvers its what you looking for; although am not sure if you are using routing right now... will prepare a quick stackblitz – Ricardo Fornes Sep 20 '20 at 17:43
  • Please take a look at this [stackblitz](https://stackblitz.com/edit/angular-k98f7w?) Here am using a route resolver to load a JSON file before rendering/loading the hello component – Ricardo Fornes Sep 20 '20 at 17:58
  • @RicardoFornes Thank you so much but the way I want to receive the data is, I want to receive it in the service itself and use the response not in the component. I just want to make a call in the component – jogo Sep 20 '20 at 18:10
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Liam Sep 25 '20 at 11:10
  • Yes I guess @Liam. Thank you for being so kind to comment here. :) – jogo Sep 26 '20 at 12:05

2 Answers2

1
  1. The JSON file is obtained asynchronously. So the dependent statements need to async as well. You could pipe in the successive function calls using the RxJS tap operator. You could find more info about async data here.

  2. If you're triggering the HTTP call from the component, I'd assume you have dependent statements over there as well. It's standard practice to return the observable from the service and subscribe to it in the component.

Try the following

Service

jsonCall(): Observable<any> {      // <-- return the observable here 
  return this.http.get("assets/abc.json").pipe(
    tap(_ => this.function())
  );
}

Component

ngOnInit() {
  this.injectService.jsonCall().subscribe(
    res => {
      console.log(res);
      // other statements that depend on `res`
    },
    err => {
      // handle error
    }
  );
}
Michael D
  • 20,838
  • 4
  • 12
  • 37
  • Thank you for you comment @Michael . Can I create an observable in a different service and subscribe it in the above service where I want to use it. Will this work? In my App component, I am simply calling the service function and thats how my requirement is. – jogo Sep 20 '20 at 17:36
  • @jogo: Yes you can inject other service to this service and trigger the call. But you cannot **_simply call_** the service function in the component. The calls are async, so the call in the component **should** be async as well. In other words, the component should subscribe in one way or other to maintain the reactive nature of the code. Please go through the SO answer I've included in the answer to understand how async call works. – Michael D Sep 20 '20 at 17:51
  • Thank you so much. I will check it out. :) – jogo Sep 20 '20 at 18:12
0
loadService(){
         //logic 
         this.jsoncall()
         }
        
        jsonCall(){
            this.http.get("assets/abc.json").subscribe(data => {
            console.log(data);
this.function1();
            })
        }  
        function1(){
            console.log('function 1');            
            this.function2();
        }
    
        function2(){
            console.log('function 2')!
            this.function3();
        }
    
        function3(){
            console.log('function 3');   
       }

Call the function 1 from inside of the service one then it will run line wise

Hitech Hitesh
  • 1,416
  • 1
  • 7
  • 15
  • Thank you for you comment. I tried that but still loads the data at the end after the execution of everything. – jogo Sep 20 '20 at 17:31