Angular re-fetch data after parameter change GET request

50
May 23, 2019, at 08:20 AM

How to re-fetch data after parameter change from: oglas/1 to oglas/2 by click, so when put URL and than click ENTER everything works, but when click on oglas/2 button when oglas/1 is rendered URL changes to oglas/2 but data is from oglas/1?

TS

import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { Post } from "../post.model";
import { ServerService } from "../server.service";
@Component({
  selector: "post",
  templateUrl: "./post.component.html",
  styleUrls: ["./post.component.css"]
})
export class PostComponent implements OnInit {
  post: Post[];
  constructor(
    private route: ActivatedRoute,
    private serverService: ServerService
  ) {}
  ngOnInit(): void {
    this.getPost();
  }
  getPost(): void {
    const id = +this.route.snapshot.paramMap.get("id");
    this.serverService.getPosts(id).subscribe(post => (this.post = post));
  }
}

Service

import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Post } from "./post.model";
import { User } from "./user.model";
import { Observable } from "rxjs";
@Injectable({ providedIn: "root" })
export class ServerService {
  usersUrl = "http://localhost:3000/users";
  postsUrl = "http://localhost:3000/posts";
  constructor(private http: HttpClient) {}
  getPosts(id: number | string): Observable<Post[]> {
    const url = `${this.postsUrl}/${id}`;
    return this.http.get<Post[]>(url);
  }
  getUser(id: number | string): Observable<User[]> {
    const url = `${this.usersUrl}/${id}`;
    return this.http.get<User[]>(url);
  }
}
Answer 1

Since your are making an API call for data in ngOnInit(), requested data may not be available by the time your component loads. And Angular might be reusing the same instance of the component, making ngOnInit() to be called only once.

You can use Angular Resolvers to ensure that you have the required data before loading the component.

1) Create a route resolver to fetch the required data before loading the route.

PostDataResolver.ts:

// ... imports
@Injectable()
export class PostDataResolver implements Resolve<any> {
 constructor(private serverService: ServerService) {}
 resolve(route: ActivatedRouteSnapshot) {
   const id = route.paramMap.get('id');
   return this.serverService.getPosts(id);
 }
}   

2) Add this resolver to your routing module:

{ path: "oglas/:id", component: PostComponent, resolve: { postData: PostDataResolver }}

3) Then access the resolved data in your component.

PostComponent.ts:

export class PostComponent implements OnInit {
  post: Post[];
  constructor(
    private route: ActivatedRoute,
    private serverService: ServerService
  ) {}
  ngOnInit(): void {
    this.post = this.route.snapshot.data.postData;
  }
}

This ensures that you have the latest and appropriate data before the component loads.

READ ALSO
Two Colum website with opposite scrolling effect [on hold]

Two Colum website with opposite scrolling effect [on hold]

How does one go about creating a website with two columns with one column moving up and the other one moving down at the same time? Example: wwwritevac

56
How do I configure to print for a thermal paper printer with react-to-print?

How do I configure to print for a thermal paper printer with react-to-print?

I'm working in a React page, and I'm using react-to-print for printingBut now I need to print in a thermal paper printer

26
the value of the property is null or undefined, not a Function object

the value of the property is null or undefined, not a Function object

I have code which functions perfectly fine in Chrome and Firefox but IE 11 (where the code MUST function) throws the following error:

28