解决不是功能

时间:2019-02-26 06:20:34

标签: angular ionic4

在Ionic V4 / Angular项目中,我创建了一个服务来调用API。
此服务在getpost之前执行一些操作,例如添加授权标头等。

@Injectable({
    providedIn: 'root'
})
export class ApiService {
    headers: HttpHeaders;

    constructor(private http: HttpClient,
                private storage: Storage,
                private loadingController: LoadingController,
                private alertController: AlertController,
                private router: Router) {
        this.storage.get('token').then(token => {
            this.headers = new HttpHeaders().set('Authorization', 'Bearer ' + token);
        });
    }

    async get<T>(url: string): Observable<T> {
        return this.init().then(async () => {
            this.http.get<T>(environment.api_url + url, {headers: this.headers}).subscribe(res => {
                return res;
            }, async err => {
                await this.checkError(err);
            });
        });
    }

    async post<T>(url: string, data: any): Observable<T> {
        return this.init().then(() => {
            this.http.post<T>(environment.api_url + url, data, {headers: this.headers}).subscribe(res => {
                return res;
            }, async err => {
                await this.checkError(err);
            });
        });
    }

    async checkError(err) {
        // if (err.status === 401) { }
        // if (err.status === 500) { }
        await this.alertController.create({
            header: 'Error',
            message: 'Sorry, Something bad happend on our side.',
            buttons: ['Ok']
        }).present();
    }

    async init() {
        const loading = await this.loadingController.create({
            spinner: 'crescent',
            message: 'Please Wait...'
        });

        await loading.present();
        // do some checking like version, connection, ...
        await loading.dismiss();
    }
}

但是当我订阅此服务的post方法时,会出现以下错误:resolve is not a function

login(loginData:any) {
    this.api.post('/auth/login', loginData).subscribe(res => { });
}

3 个答案:

答案 0 :(得分:0)

请查看我在ionic 4项目中如何处理它们。 首先,创建一个服务来处理所有http调用,如下所示。

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  /**
   *Creates an instance of DataService.
   * @param {HttpClient} http
   * @memberof DataService
   */
  constructor(private http: HttpClient) { }

  /**
   * GET data from the server
   * @param {*} url
   * @returns {Observable<any>}
   * @memberof DataService
   */
  getData(url): Observable<any> {
    return this.http.get<any>(url)
      .pipe(
        tap(response => response),
        catchError(this.handleError('getData', []))
      );
  }

  /**
   * POST call setData
   * @param {*} url
   * @param {*} data
   * @returns {Observable<any>}
   * @memberof DataService
   */
  setData(url, data): Observable<any> {
    return this.http.post<any>(url, data, { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) })
      .pipe(
        tap(response => response),
        catchError(this.handleError('setData', []))
      );
  }

  updateData(url, data): Observable<any> {
    return this.http.put<any>(url, data, { headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }) })
      .pipe(
        tap(response => response),
        catchError(this.handleError('getData', []))
      );
  }




  /**
   * Handle Http operation that failed.
   * Let the app continue.
   * @param operation - name of the operation that failed
   * @param result - optional value to return as the observable result
   */
  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      // console.error(error); // log to console instead

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }
}

然后创建另一个服务来处理与呼叫相关的模块或模块集合。这取决于您的应用程序。您必须决定。我将创建名为AppDataservice的服务以供参考

import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { map } from 'rxjs/operators';
import { DataService } from './data.service';
/**
 * This contains all the service cales to the server
 */


@Injectable({
  providedIn: 'root'
})
export class AppDataService {

  constructor(private dataService: DataService) { }

  /**
   * Login request with http post method
   */
  login(email, password) {
    const logindata = {
      email: email,
      password: password
    };
    return this.dataService.setData(`${environment.apiUrl}login`, logindata ).pipe(
      map((res) => res)
    );
  }

  /**
   * Fetch list with get request
   */
  getHelp() {
    return this.dataService.getData(`${environment.apiUrl}helpQuestions`).pipe(
      map((res) => res)
    );
  }

}

最后,您可以在以下任何组件中使用它。

 constructor(private dataService: AppDataService){
        ....
     }

    logIn() {
      this.dataService.login(this.email, this.password).subscribe(res => {
        // handle login
      }, err => {
        // handle error
      });

    }

如果适合您,请尝试。在我的项目上效果很好。

答案 1 :(得分:0)

您正在返回一个承诺,即包装了一个可观察的东西。您不能遵守承诺。您需要等待帖子的回复,然后订阅它。

答案 2 :(得分:0)

我设法解决了这样的问题:

@Injectable({
    providedIn: 'root'
})
export class ApiService {
    headers: HttpHeaders;

    constructor(private http: HttpClient,
                private storage: Storage,
                private loadingController: LoadingController,
                private alertController: AlertController,
                private router: Router) {
    }

    get<T>(url: string) {
        return this.init().then(async () => {
            const loading = await this.loadingController.create({
                spinner: 'crescent',
                message: 'Please Wait'
            });

            await loading.present();
            return this.http.get<T>(environment.api_url + url, {headers: this.headers})
                .pipe(res => {
                        return res;
                    },
                    catchError((err, caught) => {
                        return this.handleError(err, caught);
                    }),
                    finalize(async () => {
                        await loading.dismiss();
                    }));
        });
    }

    post<T>(url: string, data: any) {
        return this.init().then(async () => {
            const loading = await this.loadingController.create({
                spinner: 'crescent',
                message: 'Please Wait'
            });

            await loading.present();
            return this.http.post<T>(environment.api_url + url, data, {headers: this.headers})
                .pipe(res => {
                        return res;
                    },
                    catchError((err, caught) => {
                        return this.handleError(err, caught);
                    }),
                    finalize(async () => {
                        await loading.dismiss();
                    }));
        });
    }

    async checkError(err) {
        // if (err.status === 401) { }
        // if (err.status === 500) { }
        await this.alertController.create({
            header: 'Error',
            message: 'Sorry, Something bad happend on our side.',
            buttons: ['Ok']
        }).present();
    }

    async init() {
        this.storage.get('token').then(token => {
            this.headers = new HttpHeaders().set('Authorization', 'Bearer ' + token);
        }).then(() => {
            const loading = await this.loadingController.create({
                spinner: 'crescent',
                message: 'Please Wait...'
            });

            await loading.present();
            // do some checking like version, connection, ...
            await loading.dismiss();
        });
    }
}

以及在我的组件中:

login(loginData: LoginModel) {
    return this.api.post('/auth/login', loginData)
        .then(data => {
            data.subscribe(res => {
                // json result of api call is avaiable here
            })
        });
}