Angular에서 필요한 데이터 검색을 기다렸다가 렌더링 [Resolve]
15100 단어 Angular
Cannot read property '****' of undefined
api에서 데이터를 가져와서 표시하려고 하면 다음과 같은 오류가 발생했습니다.
해당 'name'속성은 표시되지만 오류가 나오는 것은 기분 나쁘다고 느꼈기 때문에 해결책을
조사했습니다.
버전
Angular CLI: 8.3.20
Node: 10.12.0
OS: darwin x64
Angular: 8.2.13
문제 코드
hoge.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
// 省略
export class HogeService {
constructor(private http: HttpClient) { }
getItem(id: string): Observable<any> {
return this.http.get<any>('https://fugafuga.com/api/v2/items/' + id);
}
}
app-routing.module.ts
// 省略
import { HogeComponent } from './hoge/hoge.component';
const routes: Routes = [
// 省略
{
path: 'hoge/:id',
component: HogeComponent
}
];
// 省略
hoge.component.ts
import { Component, OnInit } from '@angular/core';
import { HogeService } from '../hoge.service';
import { ActivatedRoute} from '@angular/router';
// 省略
export class HogeComponent implements OnInit {
item: any;
constructor(private route: ActivatedRoute, private hogeService: HogeService) { }
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
this.hogeService.getItem(id).subscribe(
item => {
this.item = item;
});
}
}
hoge.component.html
{{ item.name }}
가능한 원인
undefined
로 되어 있는 오브젝트의 타입 미스 → → 표시가 되어 있으므로 해당하지 않고 해결책 1 "?" 연산자 사용
null
또는 undefined
이면 이후에는 평가하지 않습니다.a?.b?.c?.d
계속 사용할 수 있습니다 이 경우,
{{ item?.name }}
라고 하면(자) 에러는 표시되지 않게 되었습니다.그렇다고는 해도, 에러가 나올 가능성이 있는 오브젝트에 매회
?
를 붙이는 것은 번거롭기 때문에, 다음의 방법을 사용했습니다.솔루션 2 Resolve 사용
Resolve 인터페이스을 구현 한 서비스를 만들고 라우팅 설정에 resolve 객체를 추가합니다.
절차
resolver 서비스 만들기
ng g s hoge-resolver
이름은 무엇이든 좋다고 생각합니다. 여기에서는
hoge-resolver
로 했습니다.다음 코드가 자동으로 생성됩니다.
hoge-resolver.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class HogeResolverService {
constructor() { }
}
Resolve 인터페이스 구현
hoge-resolver.service.ts
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { HogeService } from './hoge.service';
@Injectable({
providedIn: 'root'
})
export class HogeResolverService implements Resolve<any> {
constructor(private hogeService: HogeService) { }
resolve(route: ActivatedRouteSnapshot): Observable<any> {
const id = route.paramMap.get('id');
return this.hogeService.getItem(id);
}
}
라우팅 설정에 resolve 객체 추가
app-routing.module.ts
// 省略
import { HogeComponent } from './hoge/hoge.component';
const routes: Routes = [
// 省略
{
path: 'hoge/:id',
component: HogeComponent,
resolve: {
item: HogeResolverService
}
}
];
// 省略
여기서 resolve 내용의
item
는 나중에 참조하기 위한 이름이고 HogeResolverService
는 방금 만든 서비스입니다.구성 요소에서 참조
ActivatedRoute.data
를 subscribe하여 이전 item
를 참조할 수 있습니다.hoge.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute} from '@angular/router';
// 省略
export class HogeComponent implements OnInit {
item: any;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.data.subscribe(data => this.item = data.item);
}
}
이상으로 오류가 해결되었습니다.
결론
Resolve는 routing을 제어한다 route-guards 중 하나인 것 같기 때문에, 다른 기능도 기회가 있으면 배우고 싶습니다.
참고
Angular 공식 fetch-data-before-navigating
Reference
이 문제에 관하여(Angular에서 필요한 데이터 검색을 기다렸다가 렌더링 [Resolve]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kishida-s/items/0c96a7fde6043e8b8d76텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)