Angular抽象类TypeError

huangapple go评论138阅读模式
英文:

Angular Abstract Class TypeError

问题

以下是您要翻译的内容:

I am getting an odd Type Error when I start using Abstract Classes in Angular 16.

> Error: Uncaught (in promise): TypeError: this.httpService.get is not a function

Maybe my understanding around the useage of Abstract Classes is wrong?
It works when I remove the Abstract class and just call the http.service directly.

Models/HttpResponse.ts

  1. export class HttpResponse {
  2. status: string | undefined;
  3. data: any;
  4. success: string | undefined;
  5. message: string | undefined;
  6. }

Services/http.abstract_service.ts

  1. import { Injectable } from '@angular/core';
  2. import { Observable } from 'rxjs';
  3. @Injectable({
  4. providedIn: 'root'
  5. })
  6. export abstract class AbstractHttpService {
  7. public abstract get(url: string): Observable<any>;
  8. }

Services/http.service.ts

  1. import { AbstractHttpService } from './http.abstract_service';
  2. import { HttpClient } from '@angular/common/http';
  3. import { Injectable } from '@angular/core';
  4. import { HttpResponse } from '@models/http_response';
  5. import { Observable } from 'rxjs';
  6. import { map } from 'rxjs/operators';
  7. @Injectable({
  8. providedIn: 'root'
  9. })
  10. export class HttpService implements AbstractHttpService {
  11. constructor(private http: HttpClient){ }
  12. // GET Request
  13. get(url: string): Observable<any> {
  14. return this.http.get(url, { observe: 'response' }).pipe(
  15. map((res: any) => {
  16. let responseBody = res?.body;
  17. let result: HttpResponse;
  18. if(res){
  19. result = {
  20. status: res.status,
  21. data: responseBody.data,
  22. success: responseBody.success,
  23. message: responseBody.message
  24. }
  25. }
  26. else {
  27. console.log(`Error! HttpStatus: ${res.status}`);
  28. }
  29. return result;
  30. }));
  31. }
  32. }

Services/data.service.ts

  1. import { Injectable } from '@angular/core';
  2. import { AbstractHttpService } from './http.abstract_service';
  3. import { HttpResponse } from '@models/http_response';
  4. import { Observable } from 'rxjs';
  5. import { map } from 'rxjs/operators';
  6. @Injectable({
  7. providedIn: 'root'
  8. })
  9. export class DataService {
  10. constructor(private httpService: AbstractHttpService ){ }
  11. getMyData(): Observable<HttpResponse> {
  12. const url = `${MyApiUrl}/Data`;
  13. // This is the problem? When I make it of type HttpService and avoid the abstract class it works.
  14. const response = this.httpService.get(url);
  15. return response;
  16. }
  17. }

Pages/my/my.component.ts

  1. import { Component, OnInit } from '@angular/core';
  2. import { Result } from '@models/result';
  3. import { DataService } from '@services/data.service';
  4. import { HttpResponse } from '@models/http_response';
  5. @Component({
  6. selector: 'app-my',
  7. templateUrl: './my.component.html',
  8. styleUrls: ['./my.component.scss']
  9. })
  10. export class MyComponent implements OnInit {
  11. dataSource: Result[] = [];
  12. constructor(private dataService: DataService) { }
  13. onGetMyData() {
  14. this.dataService.getMyData().subscribe((response: HttpResponse) => {
  15. console.log(`Status: ${response.status} Success: ${response.success} Data:`, response.data.results);
  16. response.data.results.forEach((val: any) => {
  17. this.dataSource.push(Object.assign({}, val))
  18. });
  19. });
  20. }
  21. async ngOnInit() {
  22. await this.onGetMyData();
  23. }
  24. }

希望对您有所帮助!

英文:

I am getting an odd Type Error when I start using Abstract Classes in Angular 16.

> Error: Uncaught (in promise): TypeError: this.httpService.get is not a function

Maybe my understanding around the useage of Abstract Classes is wrong?
It works when I remove the Abstract class and just call the http.service directly.

Models/HttpResponse.ts

  1. export class HttpResponse {
  2. status: string | undefined;
  3. data: any;
  4. success: string | undefined;
  5. message: string | undefined;
  6. }

Services/http.abstract_service.ts

  1. import { Injectable } from &#39;@angular/core&#39;;
  2. import { Observable } from &#39;rxjs&#39;;
  3. @Injectable({
  4. providedIn: &#39;root&#39;
  5. })
  6. export abstract class AbstractHttpService {
  7. public abstract get(url: string): Observable&lt;any&gt;;
  8. }

Services/http.service.ts

  1. import { AbstractHttpService } from &#39;./http.abstract_service&#39;;
  2. import { HttpClient } from &#39;@angular/common/http&#39;;
  3. import { Injectable } from &#39;@angular/core&#39;;
  4. import { HttpResponse } from &#39;@models/http_response&#39;;
  5. import { Observable } from &#39;rxjs&#39;;
  6. import { map } from &#39;rxjs/operators&#39;;
  7. @Injectable({
  8. providedIn: &#39;root&#39;
  9. })
  10. export class HttpService implements AbstractHttpService {
  11. constructor(private http: HttpClient){ }
  12. // GET Request
  13. get(url: string): Observable&lt;any&gt; {
  14. return this.http.get(url, {observe: &#39;response&#39;}).pipe(
  15. map((res: any) =&gt; {
  16. let responseBody = res?.body;
  17. let result: HttpResponse;
  18. if(res){
  19. result = {
  20. status: res.status,
  21. data: responseBody.data,
  22. success: responseBody.success,
  23. message: responseBody.message
  24. }
  25. }
  26. else {
  27. console.log(`Error! HttpStatus: ${res.status}`);
  28. }
  29. return result;
  30. }));
  31. }

Services/data.service.ts

  1. import { Injectable } from &#39;@angular/core&#39;;
  2. import { AbstractHttpService } from &#39;./http.abstract_service&#39;;
  3. import { HttpResponse } from &#39;@models/http_response&#39;;
  4. import { Observable } from &#39;rxjs&#39;;
  5. import { map } from &#39;rxjs/operators&#39;;
  6. @Injectable({
  7. providedIn: &#39;root&#39;
  8. })
  9. export class DataService {
  10. constructor( private httpService: AbstractHttpService ){ }
  11. getMyData(): Observable&lt;HttpResponse&gt; {
  12. const url = `${MyApiUrl}/Data`;
  13. // This is the problem? When I make it of type HttpService and avoid the abstract class it works.
  14. const response = this.httpService.get(url);
  15. return response;
  16. }

Pages/my/my.component.ts

  1. import { Component, OnInit } from &#39;@angular/core&#39;;
  2. import { Result } from &#39;@models/result&#39;;
  3. import { DataService } from &#39;@services/data.service&#39;
  4. import { HttpResponse } from &#39;@models/http_response&#39;;
  5. @Component({
  6. selector: &#39;app-my&#39;,
  7. templateUrl: &#39;./my.component.html&#39;,
  8. styleUrls: [&#39;./my.component.scss&#39;]
  9. })
  10. export class MyComponent implements OnInit {
  11. dataSource: Result[] = [];
  12. constructor(private dataService: DataService) { }
  13. onGetMyData() {
  14. this.dataService.getMyData().subscribe((response: HttpResponse) =&gt; {
  15. console.log(`Status: ${response.status} Success: ${response.success} Data:`, response.data.results);
  16. response.data.results.forEach((val: any) =&gt; {
  17. this.dataSource.push(Object.assign({}, val))
  18. });
  19. });
  20. }
  21. async ngOnInit() {
  22. await this.onGetMyData();
  23. }
  24. }

Any help appreciated!

答案1

得分: 1

尝试使用 extends 而不是 implement

  1. export class HttpService extends AbstractHttpService
英文:

Try using extends instend of implement

  1. export class HttpService extends AbstractHttpService

答案2

得分: 1

你可能在混淆类:你正在使用抽象类,而不是实现它的类,因此出现了错误。

Services/data.service.ts 中,导入 http 服务类 - Services/http.service.ts,而不是抽象类 - Services/http.abstract_service.ts

尝试这样做:

Services/data.service.ts 中,

而不是:

  1. import { AbstractHttpService } from './http.abstract_service';
  2. constructor( private httpService: AbstractHttpService ){ }

使用:

  1. import { HttpService } from './http.service';
  2. constructor( private httpService: HttpService ){ }

如果你尝试创建一个具有抽象类不同实现的服务,你可以在 providers 中使用抽象类作为标记,并定义实现它的服务:

  1. providers: [ {provide:AbstractHttpService, useClass: HttpService } ]

例如,以后你可以切换到不同的实现:

  1. providers: [ {provide:AbstractHttpService, useClass: SomeDifferentHttpService } ]
英文:

You're probably mixing classes: you're using abstract class, instead of a class which implements it, hence the error.

In Services/data.service.ts, import the http service class - Services/http.service.ts, not abstract class - Services/http.abstract_service.ts:

Try this:

in Services/data.service.ts,

instead of:

  1. import { AbstractHttpService } from &#39;./http.abstract_service&#39;;
  2. constructor( private httpService: AbstractHttpService ){ }

use

  1. import { HttpService } from &#39;./http.service&#39;;
  2. constructor( private httpService: HttpService ){ }

edit

if you're trying to create a service with different implementations of abstract class, you can use abstract class as a token in providers, and define the service which implements it:

  1. providers: [ {provide:AbstractHttpService, useClass: HttpService } ]

For example, later you can switch to a different implementation:

  1. providers: [ {provide:AbstractHttpService, useClass: SomeDifferentHttpService } ]

huangapple
  • 本文由 发表于 2023年8月10日 21:38:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76876274.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定