簡體   English   中英

Angular 服務返回帶有未定義值的 Observable

[英]Angular Service returns Observable with undefined values

我有一個 angular 應用程序,它應該在 API 調用服務器后顯示一組組件,服務器將響應用戶可以根據他/她的配置文件訪問的組件。

我使用一個單獨的服務來處理和檢索用戶組件,並將其存儲在服務本身中,以便在 webapp 中輕松獲取。

我的實現如下,

API 服務進行 API 調用,

api.service.ts

import { Injectable } from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http';
import {AuthService} from './auth.service';
import {Params} from '@angular/router';
@Injectable({
  providedIn: 'root'
})


export class ApisService {

  GET_BATCH_SCHEDULE = 'http://localhost:8000/getbatchplan';
  GET_USER_STATIONS = 'http://localhost:7071/api/getUserStations';
  GET_USER_LOCATIONS = 'http://localhost:7071/api/getUserLocations';




  constructor(private httpClient: HttpClient, private authService: AuthService) { }


  getCutplanBatches() {
    return this.httpClient.get(this.GET_BATCH_SCHEDULE);
  }


  getStations(location: string) {
    if (location === undefined){
      console.log("undefined location call");
      location = 'aqua';
    }
    const params = new HttpParams()
      .set('email', this.authService.getAuthenticateduserInfo().displayableId)
      .append('location', location);

    return this.httpClient.get(this.GET_USER_STATIONS, { params: params });

  }

  getLocations() {
    const params = new HttpParams()
      .set('email', this.authService.getAuthenticateduserInfo().displayableId);

    return this.httpClient.get(this.GET_USER_LOCATIONS, { params: params });

  }


}

用於檢索和存儲與組件相關的信息的單獨服務

站服務.ts

import {Injectable} from '@angular/core';
import {ApisService} from './apis.service';
import {StationModel} from '../models/station.model';
import {BehaviorSubject, Observable} from 'rxjs';


@Injectable({
  providedIn: 'root'
})


export class StationService {
  userStations: BehaviorSubject<StationModel[]>;
  userLocation: string;

  constructor(private apiService: ApisService) {
    this.userStations = new BehaviorSubject<StationModel[]>([]);
    this.setLocationStations('aqua');

  }
  setLocation(location: string) {
    this.userLocation = location;

  }
  getLocation() {

      return this.userLocation;


  }
  setLocationStations(locationSelect: string) {
    this.apiService.getStations(locationSelect).subscribe((data: StationModel[]) => {
      this.userStations.next(data['stations']);
      console.log('setting user locations:', this.userStations);
      return this.userStations;

    });


  }
  public getLocationStations(): Observable<StationModel[]> {
    console.log('inside station service:', this.userStations);
    console.log('inside station service loc:', this.userLocation);


    return this.userStations.asObservable();

  }

}

和一個解析器,用於根據路由將必要的信息傳遞給組件。 在這里,它調用 station.service.ts 以獲取存儲的值並使用 api.service.ts 進行必要的 API 調用

station.resolver.service.ts

import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs';
import {StationService} from '../../services/station.service';
import {Injectable} from '@angular/core';
import {StationModel} from '../../models/station.model';
@Injectable({
  providedIn: 'root'
})
export class StationRouteResolver implements Resolve<StationModel> {
  currentStation: StationModel;
  constructor(private stationService: StationService) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    console.log('Resolves:', route.params['location']);

    if (this.stationService.getLocation() === undefined) {
      console.log('Initial setting:', route.params['location']);
      this.stationService.setLocation(route.params['location']);

    }else if (this.stationService.getLocation() !== route.params['location']) {
      console.log('Changing location settings:', route.params['location']);
      this.stationService.setLocation(route.params['location']);
    }else{
      console.log('Same location found!');
    }

    this.stationService.getLocationStations().subscribe((stations: StationModel[]) => {
      console.log('observer resolver:', stations);

      this.currentStation = stations.filter((station) => {
        return station.stationPath === route.params['station'];

      })[0];
      console.log('----current station:', this.currentStation);

    });
    return this.currentStation;
    // this.currentStation = this.stationService.getLocationStations().filter((station) => {
    //   return station.stationPath === route.params['station'];
    //
    // })[0];

  }

}

站組件是使用來自服務的輸入處理要顯示的組件。

station.component.ts

import {Component, Input, OnInit} from '@angular/core';
import {StationModel} from '../../models/station.model';
import {ActivatedRoute} from '@angular/router';



@Component({
  selector: 'app-station',
  templateUrl: './station.component.html',
  styleUrls: ['./station.component.scss']
})
export class StationComponent implements OnInit {
 station: StationModel;

  constructor(private route: ActivatedRoute) {

  }
  ngOnInit() {


    this.route.data.subscribe((data) => {
      this.station = data['station'];
    });
    console.log('*****params station', this.route.data['station']);


  }




}

在模板中使用 *ngIf 到 select 正確的組件

station.component.html

<app-batch-list-view *ngIf="station.stationType == 'o'"></app-batch-list-view>
<app-dashboard-view *ngIf="station.stationType == 'm'"></app-dashboard-view>
<app-print-view *ngIf="station.stationType == 'p'"></app-print-view>

問題是我在啟動和刷新頁面時遇到變量未定義錯誤,特別是在 station.component 中,因為 station.stationType 是未定義的,並且應用程序從中中斷。

但是,如果我導航返回並返回相同的路線,則此方法有效(使用 ngif 加載組件時沒有任何錯誤)。

我想知道這是因為使用了解析器還是我的實現中有問題?

抱歉,如果我的問題不太清楚。如果有人能指出問題所在,那將非常有幫助。

試試這個:這是因為未定義可空變量站或未同步調用 api。

對於第一個: station: Nullable<StationModel>

或者

對於第二個:您可以在station.component.ts中使用ngAfterViewInit()而不是ngOnInit

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM