尝试调用方法时,Angular 7 注入服务在刷新后抛出 TypeError

Posted

技术标签:

【中文标题】尝试调用方法时,Angular 7 注入服务在刷新后抛出 TypeError【英文标题】:Angular 7 injected service throws TypeError after refresh when attempting to call methods 【发布时间】:2020-06-07 10:05:06 【问题描述】:

我有一个组件DevicePage 在其构造函数中请求ServiceAdapter 的实例,然后使用该ServiceAdapter 请求ngOnInit() 中的信息。 ServiceAdatper ALSO 还请求Service 的实例进行http 调用,然后将响应转换为DevicePage 的必要对象。我的简化代码是:

@Component(
  selector: 'app-device',
  templateUrl: './device.page.html',
  styleUrls: ['./device.page.scss'],
)
export class DevicePage implements OnInit 

  private device: Device;    // beacon used in the HTML template to display info

  constructor(private activatedRoute: ActivatedRoute, private adapter: ServiceAdapter) 
  

  ngOnInit() 
    // Grab the beacon details
    this.adapter
      .getDevice(this.activatedRoute.snapshot.paramMap.get('id'))
      .subscribe(device=> this.device = device);
  


@Injectable(
    providedIn: 'root'
)
export class ServiceAdapter 

    constructor(private service: Service) 
    

    getDevice(id: string): Observable<Device> 
        this.service.getDevice(id).pipe(
            map(response => 
                return this.extractDevice(response.data).shift();
            )
        )
    

    private extractDevice(devices: Device[]) 
        return devices.map(device => <Beacon> 
            id: device.identifier,
            name: device.shadow.name
        );
    

@Injectable(
  providedIn: 'root'
)
export class Service 
  constructor(http: HttpClient) 
    this.http = http;
  

  getDevice(id): Observable<DevicesResponseV3> 
    return this.http.get<DevicesResponseV3>(URL_DEVICES)
      .pipe(catchError(err => this.handleError(err)));
  

   private handleError(error: HttpErrorResponse) 
    if (error.error instanceof ErrorEvent) 
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.message);
     else 
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Error response from $error.url ` +
        `Backend returned code $error.status ` +
        `body was: $error.message`);
    
    // return an observable with a user-facing error message
    return throwError(
      'Something bad happened; please try again later.');
  

当我第一次从最初打开应用程序并导航到该页面时,一切都按预期工作。但是,当我刷新页面时,出现以下错误: ERROR TypeError: "this.adapter.getDevice(...) is undefined"。服务本身不是未定义的,我不确定发生了什么。

我的 app.module.ts 文件的内容:

@NgModule(
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    HttpClientModule,
    IonicStorageModule.forRoot(),
    AngularFireModule.initializeApp(environment.firebase, 'herald-client-webapp'),
    AngularFireAuthModule, // imports firebase/auth, only needed for auth features
  ],
  providers: [
    StatusBar,
    SplashScreen,
     provide: RouteReuseStrategy, useClass: IonicRouteStrategy 
  ],
  bootstrap: [AppComponent]
)
export class AppModule 

【问题讨论】:

乍一看,我觉得一切都很好。您能否使用最小版本的应用重现相同的错误并通过 Stackblitz 共享? 是的,现在正在努力。 在 ngOnInit 中使用了 this.estimote.getDevice,但未声明 estimote。我不明白的另一件事是有一个EstimoteService,但没有使用。我知道这不是你的实际问题,但我找不到 this.adapter.getDevice() 的使用位置。 抱歉,这是一些遗留代码。我已经更新了。 【参考方案1】:

您是否在运行 ionic serve 时通过保存一些代码来刷新页面?

如果是这样,请不要担心它会在您发布应用程序时起作用, 设置调试器并查看:

getDevice(this.activatedRoute.snapshot.paramMap.get('id'))

id 可能为空。 也可以在进入页面时获取参数:

ionViewWillEnter() 
    this.estimote
      .getDevice(this.activatedRoute.snapshot.paramMap.get('id'))
      .subscribe(device=> this.device = device);

【讨论】:

以上是关于尝试调用方法时,Angular 7 注入服务在刷新后抛出 TypeError的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Angular 在模块文件中进行 REST 调用

Angular 4 中刷新页面和使用 routerLink 导航时的不同行为

将 angularjs 服务注入 Angular

JWT 刷新令牌 Angular

Angular 7:注入的服务未定义

自动刷新页面调用 web 服务