Kert
Kert

Reputation: 101

Angular template renders before dynamic data

I'm facing a really annoying problem - the page renders before I get the data. In $(document).ready() the names are logged correctly and there are no errors in console. However, the displayed html is empty and displays correct data after refreshing the page.

This is my component.ts file:

import {Component} from '@angular/core';
import {DataService} from '../../services/data.service';
import {ActivatedRoute, Router} from '@angular/router';
import * as $ from 'jquery/dist/jquery.min.js';
import 'jquery-ui/jquery-ui.min.js';

declare let jQuery: any;

@Component({
  selector: 'user-header',
  templateUrl: '../../templates/plan/header.html',
})
export class HeaderComponent {

  data;
  selectedCompany;
  selectedPlace;

  constructor(private dataService: DataService,
              private router: Router,
              private route: ActivatedRoute) {
    this.data = this.route.parent.snapshot.data;
    this.selectedCompany = this.data.companies[0];
    if (!this.dataService.selectedPlace.getValue()) {
      this.dataService.selectedPlace = this.selectedCompany.foodHandlingPlaces[0];
    }
    this.selectedPlace = this.selectedCompany.foodHandlingPlaces.filter(
        x => x.id === this.dataService.selectedPlace.getValue().id
    )[0];
    if (!this.selectedPlace) {
      this.selectedPlace = this.selectedCompany.foodHandlingPlaces[0];
    }

    const self = this;
    $(document).ready(function () {
      console.log('selectedCompany', self.selectedCompany.name);
      console.log('selectedPlace', self.selectedPlace.name);
    });
  }

This is part of my template (html) file:

<li class="dropdown">
  <select [(ngModel)]="selectedCompany" (change)="selectCompany()" id="company-select">
    <option *ngFor="let company of data.companies" [ngValue]="company">
      {{ company?.name }}
    </option>
  </select>
</li>
<li class="dropdown">
  <select [(ngModel)]="selectedPlace" (change)="selectPlace()" id="place-select">
    <option *ngFor="let place of selectedCompany.foodHandlingPlaces" [ngValue]="place">
      {{ place?.name }}
    </option>
  </select>
</li>

How to make the html wait for the data and then render?

Thanks in advance!

Upvotes: 0

Views: 229

Answers (1)

user4676340
user4676340

Reputation:

STOP
USING
JQUERY
WITH ANGULAR

I can't say it enough. JQuery is made for manipulating the DOM, and you should not do that in Angular.

If you want to wait for your data to be loaded, use conditions in your HTML template.

<li class="dropdown" *ngIf="selectedCompany && data.companies">
  <select [(ngModel)]="selectedCompany" (change)="selectCompany()" id="company-select">
    <option *ngFor="let company of data?.companies" [ngValue]="company">
      {{ company?.name }}
    </option>
  </select>
</li>
<li class="dropdown" *ngIf="selectedPlace && selectedCompany?.foodHandlingPlaces">
  <select [(ngModel)]="selectedPlace" (change)="selectPlace()" id="place-select">
    <option *ngFor="let place of selectedCompany.foodHandlingPlaces" [ngValue]="place">
      {{ place?.name }}
    </option>
  </select>
</li>

In your component

import { Component, OnInit } from '@angular/core';
import { DataService } from '../../services/data.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'user-header',
  templateUrl: '../../templates/plan/header.html',
})
export class HeaderComponent implements OnInit {

  data;
  selectedCompany;
  selectedPlace;

  constructor(
    private dataService: DataService,
    private router: Router,
    private route: ActivatedRoute
  ) { }

  ngOnInit() {
    this.data = this.route.parent.snapshot.data;
    this.selectedCompany = this.data.companies[0];
    if (!this.dataService.selectedPlace.getValue()) {
      this.dataService.selectedPlace = this.selectedCompany.foodHandlingPlaces[0];
    }
    this.selectedPlace = this.selectedCompany.foodHandlingPlaces.filter(
      x => x.id === this.dataService.selectedPlace.getValue().id
    )[0];
    if (!this.selectedPlace) {
      this.selectedPlace = this.selectedCompany.foodHandlingPlaces[0];
    }
  }
}

Upvotes: 4

Related Questions