Search code examples
angularionic-frameworkbehaviorsubjectsubject

Getting data from HTTP request to late in the template


I have a service where http request are created for subject and behaviorSubject. Then I get the data from the service to a page.ts (on the constructor) to display it in the template.

The code i did is working well, but the problem is the template "yelling" that the data from the subject are not arrived yet. So it give me error if I want to use it to initialize a FORM control or to display data from array.

PS: i tried with subject an behaviorSubject and i have the same problem. :( I'm sure I'm doing an conception error.

Someone have an idea about how to get data before the template is display ?

Thanks for your help

Service code with Subject and with behaviorSubject:

const INTI_DATA = [];

@Injectable({
  providedIn: 'root'
})
export class FormStorageService {
  dbSubject = new Subject<any[]>();
  dbBSubject = new BehaviorSubject(INTI_DATA);
  data$: Observable<any> = this.dbBSubject.asObservable();

  private _URL: any = '../assets/DB-Test/data.json';


  private dbData: any[] = [];

  constructor(private http: HttpClient) {}


  getDBDataBehavior() {
    this.http.get<any[]>(this._URL).subscribe((response: any[]) => {
      const value = response['DB_DATA'];
      this.dbBSubject.next(value);
    }, error => {
      console.log('Error : ', error);
      alert(error.message);
    });
  }

  getDBData() {
    this.http.get<any[]>(this._URL).subscribe((response: any[]) => {
      const value = response['DB_DATA'];
      this.dbSubject.next(value);
    }, error => {
      console.log('Error : ', error);
      alert(error.message);
    });
  }
}

Page.TS (Form2Page) with Subject call

export class Form2Page implements OnInit, OnDestroy {
  obsSubscription: Subscription;
  public dbData: DataModel[] = [];

  itemsForm: FormGroup;

  constructor(private storageService: FormStorageService) {
    // Get data from DB
    this.storageService.getDBData();
    this.obsSubscription = this.storageService.dbSubject.subscribe(
      (value: any[]) => {
        this.dbData = value;
        console.log('Value in FORM2 : ', value);
        console.log('DB Data in FORM2 in subscribe : ', this.dbData);
      },
      error => {
        console.log('erreur', error);
      }
    );
    console.log('DB Data DB Data in FORM2 : ', this.dbData);
  }

  ngOnInit() {
    console.log('DB Data in FORM2 in ngOnInit : ', this.dbData);
  }

  ngOnDestroy() {
    this.obsSubscription.unsubscribe();
  }
}

Result in the console. You can see the dbData get some data after a while

DB Data DB Data in FORM2 :  []
form2.page.ts:46 DB Data in FORM2 in ngOnInit :  []
form2.page.ts:29 Value in FORM2 :  {ITEMS: Array(1)}
form2.page.ts:30 DB Data in FORM2 in subscribe :  {ITEMS: Array(1)}

Page.TS (Form3Page) with BehaviorSubject call

export class Form3Page implements OnInit {
  obsBSubject$ = this.formStorage.data$;
  public dbData: any[] = [];

  constructor(private formStorage: FormStorageService) { 
    this.formStorage.getDBDataBehavior();
    this.obsBSubject$.subscribe(
      (value: any[]) => {
        this.dbData = value;
        console.log('Value in FORM3 : ', value);
        console.log('DB Data in FORM3 in subscribe : ', this.dbData);
      },
      error => {
        console.log('erreur', error);
      }
    );
    console.log('DB Data in FORM3 : ', this.dbData);
  }


  ngOnInit() {
    console.log('DB Data in FORM3 in ngOnInit : ', this.dbData);
  }

}

Result in the console. You can see the dbData get some data after a while

Value in FORM3 :  []
form3.page.ts:19 DB Data in FORM3 in subscribe :  []
form3.page.ts:25 DB Data in FORM3 :  []
form3.page.ts:30 DB Data in FORM3 in ngOnInit :  []

form3.page.ts:18 Value in FORM3 :  {ITEMS: Array(1)}
form3.page.ts:19 DB Data in FORM3 in subscribe :  {ITEMS: Array(1)}

Solution

  • You can use *ngIf to verify if the data already got the the frontend or not

    *ngIf=="data"
    

    Also you can check if the lenght is more than zero with another div with *ngIf to inform that the data already got here BUT with no records...