英文:
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
export class HttpResponse {
status: string | undefined;
data: any;
success: string | undefined;
message: string | undefined;
}
Services/http.abstract_service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export abstract class AbstractHttpService {
public abstract get(url: string): Observable<any>;
}
Services/http.service.ts
import { AbstractHttpService } from './http.abstract_service';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HttpResponse } from '@models/http_response';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class HttpService implements AbstractHttpService {
constructor(private http: HttpClient){ }
// GET Request
get(url: string): Observable<any> {
return this.http.get(url, { observe: 'response' }).pipe(
map((res: any) => {
let responseBody = res?.body;
let result: HttpResponse;
if(res){
result = {
status: res.status,
data: responseBody.data,
success: responseBody.success,
message: responseBody.message
}
}
else {
console.log(`Error! HttpStatus: ${res.status}`);
}
return result;
}));
}
}
Services/data.service.ts
import { Injectable } from '@angular/core';
import { AbstractHttpService } from './http.abstract_service';
import { HttpResponse } from '@models/http_response';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private httpService: AbstractHttpService ){ }
getMyData(): Observable<HttpResponse> {
const url = `${MyApiUrl}/Data`;
// This is the problem? When I make it of type HttpService and avoid the abstract class it works.
const response = this.httpService.get(url);
return response;
}
}
Pages/my/my.component.ts
import { Component, OnInit } from '@angular/core';
import { Result } from '@models/result';
import { DataService } from '@services/data.service';
import { HttpResponse } from '@models/http_response';
@Component({
selector: 'app-my',
templateUrl: './my.component.html',
styleUrls: ['./my.component.scss']
})
export class MyComponent implements OnInit {
dataSource: Result[] = [];
constructor(private dataService: DataService) { }
onGetMyData() {
this.dataService.getMyData().subscribe((response: HttpResponse) => {
console.log(`Status: ${response.status} Success: ${response.success} Data:`, response.data.results);
response.data.results.forEach((val: any) => {
this.dataSource.push(Object.assign({}, val))
});
});
}
async ngOnInit() {
await this.onGetMyData();
}
}
希望对您有所帮助!
英文:
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
export class HttpResponse {
status: string | undefined;
data: any;
success: string | undefined;
message: string | undefined;
}
Services/http.abstract_service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export abstract class AbstractHttpService {
public abstract get(url: string): Observable<any>;
}
Services/http.service.ts
import { AbstractHttpService } from './http.abstract_service';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HttpResponse } from '@models/http_response';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class HttpService implements AbstractHttpService {
constructor(private http: HttpClient){ }
// GET Request
get(url: string): Observable<any> {
return this.http.get(url, {observe: 'response'}).pipe(
map((res: any) => {
let responseBody = res?.body;
let result: HttpResponse;
if(res){
result = {
status: res.status,
data: responseBody.data,
success: responseBody.success,
message: responseBody.message
}
}
else {
console.log(`Error! HttpStatus: ${res.status}`);
}
return result;
}));
}
Services/data.service.ts
import { Injectable } from '@angular/core';
import { AbstractHttpService } from './http.abstract_service';
import { HttpResponse } from '@models/http_response';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor( private httpService: AbstractHttpService ){ }
getMyData(): Observable<HttpResponse> {
const url = `${MyApiUrl}/Data`;
// This is the problem? When I make it of type HttpService and avoid the abstract class it works.
const response = this.httpService.get(url);
return response;
}
Pages/my/my.component.ts
import { Component, OnInit } from '@angular/core';
import { Result } from '@models/result';
import { DataService } from '@services/data.service'
import { HttpResponse } from '@models/http_response';
@Component({
selector: 'app-my',
templateUrl: './my.component.html',
styleUrls: ['./my.component.scss']
})
export class MyComponent implements OnInit {
dataSource: Result[] = [];
constructor(private dataService: DataService) { }
onGetMyData() {
this.dataService.getMyData().subscribe((response: HttpResponse) => {
console.log(`Status: ${response.status} Success: ${response.success} Data:`, response.data.results);
response.data.results.forEach((val: any) => {
this.dataSource.push(Object.assign({}, val))
});
});
}
async ngOnInit() {
await this.onGetMyData();
}
}
Any help appreciated!
答案1
得分: 1
尝试使用 extends
而不是 implement
:
export class HttpService extends AbstractHttpService
英文:
Try using extends instend of implement
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
中,
而不是:
import { AbstractHttpService } from './http.abstract_service';
constructor( private httpService: AbstractHttpService ){ }
使用:
import { HttpService } from './http.service';
constructor( private httpService: HttpService ){ }
如果你尝试创建一个具有抽象类不同实现的服务,你可以在 providers
中使用抽象类作为标记,并定义实现它的服务:
providers: [ {provide:AbstractHttpService, useClass: HttpService } ]
例如,以后你可以切换到不同的实现:
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:
import { AbstractHttpService } from './http.abstract_service';
constructor( private httpService: AbstractHttpService ){ }
use
import { HttpService } from './http.service';
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:
providers: [ {provide:AbstractHttpService, useClass: HttpService } ]
For example, later you can switch to a different implementation:
providers: [ {provide:AbstractHttpService, useClass: SomeDifferentHttpService } ]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论