AlexanderBelov
@AlexanderBelov
Frontend developer

Variable is undefined / Angular 4 service?

Пытаюсь отрендерить во view детали выбранного элемента. Но в *ngIf переменная не передаётся. Причём сама разметка рендерится (то, что вне условия *ngIf).

Прошу помочь выстроить правильное отслеживание переменной, передаваемой сервисом.

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"
    }]
 }


Основной трабл в том, что в details.component.ts вот в этой функции не определяется переменная "person", соответственно, не выводится в рендер.
(Отдельный фрагмент кода выше для удобства)
ngOnInit(): void {
    this.route.params.forEach((params: Params) => {
        let id = +params['id'];
        this._PersonService.getPerson(id)
    .map(person => this.person = person).subscribe();
    })
  }
  • Вопрос задан
  • 827 просмотров
Пригласить эксперта
Ответы на вопрос 2
navix
@navix
Angular & TypeScript
Тут есть несколько не совсем корректных мест.
Но, если говорить об основной проблеме, то нужно смотреть, что передается в метод getPerson.

this.route.params - это Observable и при изменении роута, там приходят новые значения.

Так же не следует создавать сайд-эффекты (влиять на переменные все самой функции) на мап-операторе, ошибки связанные с этим достаточно сложно отлавливать.

Я бы переписал этот код так:
ngOnInit() {
  this.route.params.pluck('id').subscribe(id => {
    this._PersonService.getPerson(+id).subscribe(person => this.person = person);
  });
}


Все еще возможно, что это не решит проблему, но поможет двигаться дальше.
Ответ написан
@timurkin
Удалил свой предыдущий комментарий, т.к. неправильно прочитал вопрос. В вашем случае должно помочь (только что проверил у себя - работает):
ngOnInit(): void {
    this.route.params.forEach((params: Params) => {
        let id = +params['id'];
        this._PersonService.getPerson(id).subscribe(person => this.person = person);
    })
  }

Проверьте, получается ли persons.json и существует ли пользователь с таким айдишником
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы