A
A
Alexander Belov2017-10-23 20:37:48
JavaScript
Alexander Belov, 2017-10-23 20:37:48

Variable is undefined / Angular 4 service?

I'm trying to render the details of the selected element in the view. But in *ngIf the variable is not passed. Moreover, the markup itself is rendered (what is outside the *ngIf condition).
I ask you to help build the correct tracking of the variable transmitted by the service.
person.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import { IPerson } from '../persons/person';

@Injectable()
export class PersonService {
  private _personUrl = './assets/persons.json';

  constructor(private _http:Http){}

  getPersons(): Observable<IPerson[]> {
    return this._http.get(this._personUrl)
    .map((response: Response) => <IPerson[]>response.json().personsData)
  }

   getPerson(id:number): Observable<IPerson>{
    return this.getPersons()
    .map(persons => persons.find(person => person.id === id));
  }
}
}

details.component.html
<div *ngIf="person" class="container">
  <h3>Person Details</h3>
  <div class="col-md-12">
     <div>{{ person.name }}</div>
     <div>{{ person.id }}</div>
  </div>

  <button (click)="goBack()">Back</button>
</div>

details.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { PersonService } from '../service/person.service';
import { IPerson } from '../persons/person';

@Component({
   selector: 'app-details',
   templateUrl: './details.component.html',
  styleUrls: ['./details.component.css'] 
})
export class DetailsComponent implements OnInit {
  public person: IPerson;

  constructor(
    private _PersonService: PersonService,
    private route: ActivatedRoute
    ) { }

  ngOnInit(): void {
    this.route.params.forEach((params: Params) => {
        let id = +params['id'];
        this._PersonService.getPerson(id)
    .map(person => this.person = person).subscribe();
    })
  }
}

persons.json
{
  "personsData" : [
    {
      "id": 1,
      "name": "KC"
    },
    {
      "id": 2,
      "name": "KN"
    },
    {
      "id": 3,
      "name": "DG"
    }]
 }

The main problem is that the "person" variable is not defined in details.component.ts in this function , so it is not displayed in the renderer. (Separate code snippet above for convenience)
ngOnInit(): void {
    this.route.params.forEach((params: Params) => {
        let id = +params['id'];
        this._PersonService.getPerson(id)
    .map(person => this.person = person).subscribe();
    })
  }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sasha Novik, 2017-10-23
@navix

There are a few not quite correct places.
But, if we talk about the main problem, then you need to look at what is passed to the getPerson method.
this.route.params is an Observable and when the route changes, new values ​​come in there.
Also, you should not create side effects (influence the variables of all the function itself) on the map operator, the errors associated with this are quite difficult to catch.
I would rewrite this code like this:

ngOnInit() {
  this.route.params.pluck('id').subscribe(id => {
    this._PersonService.getPerson(+id).subscribe(person => this.person = person);
  });
}

It's still possible that this won't solve the problem, but will help move forward.

T
Timurkin, 2017-10-23
@timurkin

Deleted my previous comment, tk. I misread the question. In your case, it should help (I just checked it myself - it works):

ngOnInit(): void {
    this.route.params.forEach((params: Params) => {
        let id = +params['id'];
        this._PersonService.getPerson(id).subscribe(person => this.person = person);
    })
  }

Check if you get persons.json and if there is a user with that id

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question