Ctfrancia
Ctfrancia

Reputation: 1588

Angular - How to make sure that data is loaded only once

When the page is loaded, the data is correctly fetched, and shown, then when leaving the page the data is fetched again and doubled onto the current array. If I have Item: A,B,C then I will have A,B,CA,B,C.

Right now I have the component putting a simple if to check if I need to fetch the data again or not. However, it appears that it is bypassed. I have looked at this and this as well as this.

//home.ts

export class Home implements OnInit, OnDestroy{
  conversations: Array<any>; 

async ngOnInit() {
  this._chatInit();
}

private async _chatInit() {
  this.dataService.loadConversations(); //getter for local storage

  const data = this.messageStorage.hasChats();

  if (data.length) {
    //there is data already loaded
    this.conversations = data;
  } else {
    //there is an empty array, subscribe to it.
    this.messageStorage
    .getChatList$()
    .subscribe(conversation => {
      console.log('Conversation', conversation)
      this.conversations = conversation;
    });
  }
}

//dataService
export class DataService {

  //the object where it is all stored
  private conversations: any = {
    peerToPeer: {},
    groups: {},
  };

  private listOfChats: Array<any> = new Array<any>();
  private bsListOfChats$: BehaviorSubject<any> = new BehaviorSubject<any>(this.listOfChats); 

  public loadConversations() {
    this.storage.get('conversations').then(chat=> {
      this.conversations = chat;
      this.formatChats(this.conversations);//converts the Object to an Array so *ngFor directive can be used
   });
  }

  public hasChats() {
    return this.listOfChats;
  }

  public getChatList$() {
    return this.bsListOfChats$;
  }

}

To clarify, what I want to happen is to load n chats once. When I leave the page and return I want the same n to load, no more, no less.

thanks guys for any help!

Upvotes: 0

Views: 1442

Answers (2)

chestas
chestas

Reputation: 124

look at TransferState it is used for transfer data between server side (angular universal) and client side, but I think it is ok to use it only for client side

import {makeStateKey, TransferState} from '@angular/platform-browser';

export class DataService {

//the object where it is all stored
private conversations: any = {
    peerToPeer: {},
    groups: {},
};

constructor(
    private state: TransferState,
) {

}

private listOfChats: Array<any> = new Array<any>();
private bsListOfChats$: BehaviorSubject<any> = new BehaviorSubject<any>(this.listOfChats);

public loadConversations() {
    const stateKey = makeStateKey('conversations'); // 1 create stateKey
    const data = this.state.get(stateKey, null as any); // 2 get data from state
    if (data) { // 3 if data in state use it
        this.conversations = data;
    } else {
        this.storage.get('conversations').then(chat=> {
            this.conversations = chat;
            this.formatChats(this.conversations);//converts the Object to an Array so *ngFor directive can be used
            this.state.set(stateKey, {...this.conversations}); // 4 set data to storage
        });
    }
}

public hasChats() {
    return this.listOfChats;
}

public getChatList$() {
    return this.bsListOfChats$;
}

}

fast edit your code, could be rewritten in better way

Upvotes: 1

Y_Moshe
Y_Moshe

Reputation: 432

do this:

@Component({
  //...
  changeDetection: ChangeDetectionStrategy.OnPush
})

check out: https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/

Upvotes: 0

Related Questions