2

I need to do something quit simple - I would like to do a one time http request to a static data - I would like to do it either when the application starts or as "lazy-loading", when needed. I would like to send the http request one time and set a variable (member -> property) with the returning results, so I can use that property later on instead of doing another http request. Below is my code - is it the best practice solution ? Any remark\improvement\another way of doing it - would be appreciated.

The "lut" is for "lookup table" dat -> the static data.

@Injectable({providedIn: 'root'})
export class lutData
  {
    _someData : somedataType[] = null;
    constructor(private lutService : LutService){} //The service is a simple http service           
    public get SomeData() : somedataType[] {
      if (this._someData){
        return this._someData;
      }
      else {
        this.lutService.getSomeLutData().subscribe(result =>{
          this._someData = result;
          return this._someData;
        });
      }
    }
}

This is the component that should use the data: I'm using injection, but maybe there's a better way doing it.

export class XXX_Component {
  someData : somedataType[];    
  constructor(private lookUpData : lutData) { } 
  ngOnInit() {
    this.setLutData();
  }     
  setLutData() {
    this.someData = this.lookUpData.SomeData; 
  }
}
1
  • Keep in mind that you cannot return anything from inside a subscribe(). return this._someData; isn't doing anything at all. Also you should consider using operators such as shareReplay which use ReplaySubject under the hood to "cache" n number of results. Commented Aug 26, 2019 at 14:51

2 Answers 2

1

What I would do is take the best of Observable:

@Injectable({providedIn: 'root'})
export class LutData
  {
    _someData : somedataType[] = null;
    constructor(private lutService : LutService){} //The service is a simple http service           
    public someData() : Observable<somedataType[]> {
      if (this._someData){
        return of(this._someData);
      }
      else {
        const req = this.lutService.getSomeLutData();
        req.subscribe(data=> this._someData = data);
        return req;
      }
    }
}

Component

export class XXX_Component {
  someData$ : Observable<somedataType[]> = this.lookUpData.someData();  
  constructor(private lookUpData : LutData) { } 
}

Then in your component template use the async pipe:

<div *ngFor="let item of (someData$ | async)">
  {{item}}
</div>
Sign up to request clarification or add additional context in comments.

Comments

0

Store data in a service is very good way of making data available for all the components and also maintain the consistency. But calling the http request whenever your project is start or app is render on the device, depend on the use case.

It's good, If you need updated data at least once whenever user land on your page like, user_details, user jwt keys etc.

Consider an example, suppose you have a page where you listing pricing/packages details of your services. And these information are not changing very frequently. For this example calling http service at the time of start your project is unnecessary.

For this type of application, where your data are not changing very frequently you can call http once and after that store the response in your native storage with some validation roles. So whenever your page is open 1. Look into native storage for the data. 2. If found and pass the validation role. 3. Then store in a service for future use. 4. If not found or not able to pass validation role. 5. Call http request again. 6. Save the response to native storage with same validation role. 7. And also set the response in your service for future use.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.