首页 > 解决方案 > 如何解决问题无法读取未定义角度和离子 4 的属性“订阅”

问题描述

我是角度框架和离子的初学者。

我使用 ionic 4 和 angular 创建了一个药房项目...

但是当我尝试添加药房时,函数 onCreatePharmaG() 出现错误:

'void'类型上不存在属性'subscribe'!

我不明白为什么?

那我能做什么?

这是我的代码:

药房.service.ts

import { Injectable } from '@angular/core';
import { Pharmacie } from './pharmacie.model';
import { AuthService } from '../auth/auth.service';
import { BehaviorSubject, of } from 'rxjs';
import { take, map, tap, delay, switchMap } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';


interface PharmacyData{
   DateFin: string;
   dateDeb: string;
   adresse: string;
   imageUrl: string;
   telephone: number;
   nom: string;
   userId: string;
  }

@Injectable({
  providedIn: 'root'
})
export class PharmaciesService {
  private _pharmacies =  new BehaviorSubject<Pharmacie[]>([]) ;

  get pharmacies(){
    return this._pharmacies.asObservable();
  }

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

  fetchPharmacies(){
    return this.http.get<{[key: string]: PharmacyData}>('https://pharmacies.firebaseio.com/pharmacies.json').pipe(map(resData => {
    const pharmacies = [];
    for(const key in resData){
      if(resData.hasOwnProperty(key)){
        pharmacies.push(new Pharmacie(key,
          resData[key].nom,
          resData[key].adresse,
          resData[key].imageUrl,
          resData[key].telephone,
          new Date(resData[key].dateDeb),
          new Date(resData[key].DateFin),
          resData[key].userId));
      }
    }
    return pharmacies;
    // return [];
    }),
    tap(pharmacies => {
      this._pharmacies.next(pharmacies);
    })
    );
  }

  getPharmacy(id: string){
  return this.http.get<PharmacyData>(`https://pharmacies.firebaseio.com/pharmacies/${id}.json`
   ).pipe(map(pharmacyData => {
    return new Pharmacie(id,
      pharmacyData.nom,
      pharmacyData.adresse,
      pharmacyData.imageUrl,
      pharmacyData.telephone,
      new Date(pharmacyData.dateDeb),
      new Date(pharmacyData.DateFin),
      pharmacyData.userId);
   }));
  }

  AddPharmacyy(
   nom: string,
   adresse: string,
   telephone: number,
   dateDeb: Date,
   DateFin: Date){
     let generatedId: string;
     let newPharmacy: Pharmacie;
     this.authService.userId.pipe(take(1), switchMap(userId => {
      if(!userId){
        throw new Error('id non trouvé !');
      }
       newPharmacy = new Pharmacie(
       Math.random().toString(),
        nom,
        adresse,
        'https://cdn.1min30.com/wp-content/uploads/2018/05/Logo-Pharmacie-500x263.jpg',
        telephone,
        dateDeb,
        DateFin,
        userId
        );
        return this.http.post<{name: string}>('https://pharmacies.firebaseio.com/pharmacies.json', {...newPharmacy, id: null});
     }),
      switchMap(resData => {
        generatedId = resData.name;
        return this.pharmacies;
      }),
      take(1),
      tap(pharmacies => {
        newPharmacy.id = generatedId;
          this._pharmacies.next(pharmacies.concat(newPharmacy));
      })
      );
   }

   updatePharmacy(
    pharmacieId: string,
    nom: string,
    adresse: string,
    telephone: number,
    dateDeb: string,
    DateFin: string
    ){
      let updatedPharmacies: Pharmacie[];
       return this.pharmacies.pipe(
        take(1),
        switchMap(pharmacies => {
          if(!pharmacies || pharmacies.length <= 0){
           return this.fetchPharmacies; 
          }else{
            return of(pharmacies);
          }
        }),
        switchMap(pharmacies => {
          const updatedPharmacyIndex = pharmacies.findIndex(ph => ph.id === pharmacieId);
          const updatedPharmacies = [...pharmacies];
          const oldPharma = updatedPharmacies[updatedPharmacyIndex];
          updatedPharmacies[updatedPharmacyIndex] = new Pharmacie(oldPharma.id, nom, adresse, oldPharma.imageUrl, telephone, oldPharma.dateDeb, oldPharma.DateFin, oldPharma.userId);
          return this.http.put(
            `https://pharmacies.firebaseio.com/pharmacies/${pharmacieId}.json`,
            { ...updatedPharmacies[updatedPharmacyIndex], id: null}
            );
        }),
        tap(() =>{
        this._pharmacies.next(updatedPharmacies);
        }));   
    }

   cancelPharmacy(pharmacieId: string){
    return this.http.delete(`https://pharmacies.firebaseio.com/pharmacies/${pharmacieId}.json`).pipe(
      switchMap(() => {
      return this.pharmacies;
      }),
      take(1),
      tap(pharmacies => {
         this._pharmacies.next(pharmacies.filter(pha => pha.id !== pharmacieId));
       })
      );
   }
   
}

添加-pharamcie.page.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { PharmaciesService } from '../../pharmacies.service';
import { Router } from '@angular/router';
import { LoadingController } from '@ionic/angular';

@Component({
  selector: 'app-ajouter-pharmacie',
  templateUrl: './ajouter-pharmacie.page.html',
  styleUrls: ['./ajouter-pharmacie.page.scss'],
})
export class AjouterPharmaciePage implements OnInit {
  form: FormGroup;

  constructor(
    private pharmaciesService: PharmaciesService,
    private router: Router,
    private loadingCtrl: LoadingController
  ) { }

  ngOnInit() {
    this.form = new FormGroup({
      nomPha: new FormControl(null, {
        updateOn: 'blur',
        validators: [Validators.required]
      }),
      AdrPha: new FormControl(null, {
        updateOn: 'blur',
        validators: [Validators.required, Validators.maxLength(180)]
      }),
      numPharmacie: new FormControl(null, {
        updateOn: 'blur',
        validators: [Validators.required, Validators.min(1)]
      }),
      dateDebut: new FormControl(null, {
        updateOn: 'blur',
        //validators: [Validators.required]
      }),
      dateFin: new FormControl(null, {
        updateOn: 'blur',
        // validators: [Validators.required]
      })
    });
  }

  onCreatePharmaG(){
    if(!this.form.valid){
      return;
    }
    this.loadingCtrl.create({
      message: 'Création d\'une pharmacie...'
    }).then( loadingEl => {
    loadingEl.present();
    this.pharmaciesService.AddPharmacyy(
      this.form.value.nomPha,
      this.form.value.AdrPha,
      +this.form.value.numPharmacie,
      new Date(this.form.value.dateDebut),
      new Date(this.form.value.dateFin)
      ).subscribe(() => {
        loadingEl.dismiss();
        this.form.reset();
        this.router.navigate(['/pharmacies/syndicat']);
      });
    });
  }

}

辛迪加.page.ts

import { Component, OnInit } from '@angular/core';
import { Pharmacie } from '../pharmacie.model';
import { PharmaciesService } from '../pharmacies.service';
import { IonItemSliding, LoadingController } from '@ionic/angular';
import { Subscription } from 'rxjs';
import { Router } from '@angular/router';

@Component({
  selector: 'app-syndicat',
  templateUrl: './syndicat.page.html',
  styleUrls: ['./syndicat.page.scss'],
})
export class SyndicatPage implements OnInit {
  pharmacies: Pharmacie[];
  isLoading = false;
  // listedLoadedPharmacies: Pharmacie[];
  private pharmaciesSub: Subscription;

  constructor(private pharmaciesService: PharmaciesService,
    private router: Router,
    private loadingCtrl: LoadingController) { }


  ngOnInit() {
    this.pharmaciesSub= this.pharmaciesService.pharmacies.subscribe(pharmacies =>{
    this.pharmacies = pharmacies;
    // this.listedLoadedPharmacies = this.loadedPharmacies.slice(1);
    });
  }

  ionViewWillEnter(){
    this.isLoading = true;
    this.pharmaciesService.fetchPharmacies().subscribe(() => {
      this.isLoading = false;
    });
  }
 
  
  onCancelPharmacy(pharmacieId: string, slidingEl: IonItemSliding){
    slidingEl.close();
    this.loadingCtrl.create({message: 'Suppression...'}).then(loadingEl => {
      loadingEl.present();
    this.pharmaciesService.cancelPharmacy(pharmacieId).subscribe(() => {
      loadingEl.dismiss();
    });
    });
  }

  onEdit(pharmacieId: string, slidingItem: IonItemSliding){
    slidingItem.close();
    this.router.navigate(['/', 'pharmacies', 'liste-pharmacies', 'modifier', pharmacieId ]);
   // console.log('Editing item', pharmacieId);
  }

  ngOnDestroy(){
    if(this.pharmaciesSub){
      this.pharmaciesSub.unsubscribe();
    }
  }


}

标签: angularionic-frameworkionic4

解决方案


您尝试订阅的值是undefined.

具体来说,您的AddPharmacyy方法的返回类型为 ,void因为它没有返回语句。

你需要放在return前面this.authService.userId.pipe

像这样的错误可能出现在您的代码的更多部分,因此请务必检查它。我还建议遵循最佳实践指南,并在您的应用程序中包含一个 linter 以消除此类错误。


推荐阅读