1

In my angular project, I have a following setup:

API.ts: API functions to get data

...
export class dataAPI {
   info: any = null;

   getDataFromAPI(name){
     this.http.get(name)...
       .subscribe(data =>{
          this.info = data;  //This will have returned data
       }
   }  
}

Main.ts: Main page ts file where the API function is used

  import { dataAPI }  from '../API.ts';

  @Component({
     templateUrl: 'main_page.html'
  }) 

  export class mainPage{      
      returnedData: any;

      constructor(public myAPI: dataAPI){};

      ngOnInit(){
          this.returnedData = this.myAPI.getDataFromAPI('steve'); //????
      }        
  }

main_page.html: Need to show the returned data from API function

 <div class="main" *ngIf="returnedData">
     {{returnedData}}
 </div>   

Question

From API.ts file, this.info will need to somehow passed onto main.ts. How do I do this? Any help will be much appreciated!

6
  • What is the output of this code ? Commented Aug 14, 2017 at 7:40
  • 1
    Why not return an Observable from service function and subscribe from it at your component? refer stackoverflow.com/questions/45652646/… Commented Aug 14, 2017 at 7:42
  • Seems like you are trying to return data from subscribe, which is not possible, so it's probably a dupe of this Commented Aug 14, 2017 at 7:42
  • Don't subscribe from the service. Return the observable, and subscribe in the component, or in the view using the async pipe. Commented Aug 14, 2017 at 7:43
  • The data returned is like a paragraph or phone number. Because there are many occasions and in many different files that I need to use the same api, I though I would make a function that I can use in multiple files. Commented Aug 14, 2017 at 7:49

2 Answers 2

4

Option 1

I would do something like this

getDataFromAPI(name){
   //do not subscribe in this service! Return the observable.
    return this.http.get(name)...

   } 

And in your mainPage

export class mainPage{      
      returnedData: any;

      constructor(public myAPI: dataAPI){};

      ngOnInit(){
         this.myAPI.getDataFromAPI('steve')
          .subscribe( data=>{
             this.returnedData = data; //SUBSCRIBE HERE
           }); 
      }        
  }

Option 2 Almost the same with option 1, but using an async pipe like this

export class mainPage{      
      returnedData$ : Observable<any>;

      constructor(public myAPI: dataAPI){};

      ngOnInit(){
         this.returnedData$ = this.myAPI.getDataFromAPI('steve');
      }        
  }

And in your template

<div class="main">
     {{ returnedData$ | async)}}
 </div>   

Option 3 Here's another option and something that I would not recommend. Since you declare the service as public, you can use it as well in your template like this directly .

 <div class="main" *ngIf="myAPI.info">
    {{returnedData$ | async}}
 </div>   

and declare your info as public in your service.

Sign up to request clarification or add additional context in comments.

2 Comments

But NOTE: The above will only work if API.ts is a service. It's not clear from the OP that it is a service and not just a simple class.
@DeborahK thank you for commenting. I didn't notice that. I just assumed that it is a service. I agree that the question was not clear whether it was from a service or class
2

Starting here may be helpful: https://angular.io/guide/http

Note that the sample code in the Angular docs does not yet show the "best practice" of using a service for the Http calls. But it does explain how http works and returns an observable to your code.

Here is an example service that returns a product. You can adjust this to meet your needs:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';

import { IProduct } from './product';

@Injectable()
export class ProductService {
    private _productUrl = './api/products/products.json';

    constructor(private _http: HttpClient) { }

    getProducts(): Observable<IProduct[]> {
        return this._http.get<IProduct[]>(this._productUrl)
            .do(data => console.log('All: ' + JSON.stringify(data)))
            .catch(this.handleError);
    }

    private handleError(err: HttpErrorResponse) {
        // in a real world app, we may send the server to some remote logging infrastructure
        // instead of just logging it to the console
        let errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
        console.error(errorMessage);
        return Observable.throw(errorMessage);
    }
}

And here is the component code that calls the service, receiving the data:

import { Component, OnInit } from '@angular/core';

import { IProduct } from './product';
import { ProductService } from './product.service';

@Component({
    templateUrl: './product-list.component.html'
})
export class ProductListComponent implements OnInit {
    products: IProduct[] = [];
    errorMessage = '';

    constructor(private _productService: ProductService) {

    }

    ngOnInit(): void {
        this._productService.getProducts()
                .subscribe(products => this.products = products;,
                           error => this.errorMessage = <any>error);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.