Açıkça yazılmış tipli dizi, Http.Get'ten o tip olarak doldurulmuyor gibi görünüyor. Angular, Typescript, Javascript
Yani bu proje için iki sınıf tanımladım:
Müşteriİşi
export class CustomerJob {
partNumber?: string;
revision?: string;
description?: string;
dueDate?: Date;
customer?: string;
purchaseOrderNumber?: string;
quantityDue?: number;
quantityShipped?: number;
salesOrderNumber?: number;
salesOrderLineNumber?: number;
salesOrderLineLotNumber?: number;
itemID?: number;
salesOrderCreateDate?: Date;
salesOrderLineCreateDate?: Date;
salesOrderLineLotCreateDate?: Date;
progress?: number;
shipVia?: string;
status?: string;
customDescription?: string;
shippingLocation?: string;
documents?: DocumentFile[];
openQuantity?: number = 0;
}
BelgeDosyası
export class DocumentFile {
id?: number;
url?: string;
fileName?: string;
extension?: string;
extensionWithoutPeriod?: string;
isImageFile: boolean = false;
setup () {
console.warn('doing setup for document');
// get name of file (filename.extension). need to remove all the \\ stuff basically
let _stringArray = this.url?.split('\\');
// the last one in this split is the filename and extension
let _filenameWithExtension = _stringArray![_stringArray!.length - 1];
// split this by period
let _filenameSplit = _filenameWithExtension.split('.');
// first one in array is the filename
this.fileName = _filenameSplit![0];
// second is extension
this.extensionWithoutPeriod = _filenameSplit![1];
this.extension = '.' + this.extensionWithoutPeriod;
}
}
Benim şöyle görünen bir servisim var:
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { firstValueFrom } from 'rxjs';
import { CustomerJob, DocumentFile } from '../dataModels/data-models';
import { LoginService } from '../services/login.service';
@Injectable({
providedIn: 'root'
})
export class JobService {
constructor(private http: HttpClient, private loginService: LoginService) { }
jobs?: CustomerJob[] = [];
async getCustomerJobs () {
let headers = new HttpHeaders().set('APIKey', this.loginService.loginInformation!.apiKey);
try {
this.jobs = await firstValueFrom(this.http.get<CustomerJob[]>('https://XXXXX', { headers: headers }));
// do some modifications to them
this.jobs.forEach(function (j) {
// quantity
if (j.quantityDue != undefined && j.quantityShipped != undefined) {
j.openQuantity = j.quantityDue - j.quantityShipped;
}
// document stuff
if (j.documents != undefined) {
j.documents.forEach(d => {
// console.warn('setting up F');
if (d == undefined) {
console.warn('this document is undefined');
}
else {
//d = Object.assign(d, j.documents[i]);
console.warn('this document is defined: ' + d.id + ', ' + d.url);
d.setup();
console.warn(d.fileName);
}
});
}
else {
console.warn('this one DOES NOT have documents');
}
});
}
catch (error: any) {
console.error('CATCH ERROR: ' + error.message);
}
return this.jobs;
}
}
Bunu TryCatch üzerinden konsolda aldığım hata.
d.setup is not a function
Burada önemli olan şey, aslında hemen öncesindeki satırda bazı bilgileri doğru şekilde yazdırıyor olmasıdır:
console.warn('this document is defined: ' + d.id + ', ' + d.url);
Sonunda anladım ki sorun muhtemelen "d"nin aslında bir DocumentFile türü olmaması. Bunun nedenini çözemedim çünkü CustomerJob sınıfında dizi özellikle bir DocumentFile dizisi olarak türlendirilmiş. Yani bir noktada, tahminimce Http.Get üzerinden CustomerJobs dizisini oluştururken, özel olarak türlendirilmiş DocumentFile dizisini anonim nesneler dizisine veya başka bir şeye dönüştürüyor.
Bunun doğru olduğunu biliyorum çünkü kodu şöyle değiştirdiğimde sorunsuz çalışıyor:
j.documents.forEach(d => {
// console.warn('setting up F');
if (d == undefined) {
console.warn('this document is undefined');
}
else {
let doc: DocumentFile = new DocumentFile();
Object.assign(doc, d);
console.warn('this document is defined: ' + doc.id + ', ' + doc.url);
doc.setup();
console.warn(doc.fileName);
}
});
Ben C# kullanmaktan geliyorum, bu yüzden JavaScript gibi gevşek türlü dillerle her zaman sorun yaşıyorum. Bu çok sinir bozucu. Yardımınız için şimdiden teşekkür ederim.
Cevap #1
Sorununuz, HttpClient sunucudan gelen sonuçları serileştirirken, aslında hangi biçimde olmasını istediğini bilme yolunun olmamasıdır. TypeScript arayüzleri ve tipleri tamamen derleme zamanı öğeleridir, C#’ta yansıma kullanabileceğinizin aksine. Geliştirici araçlarını açıp API çağrınızdan gelen sonuçlara bakarsanız, verilerinizin saf JSON olduğunu göreceksiniz. HttpClient da bunu görür.
Ağ sınırındaki TypeScript arayüzleri sadece belgelerdir, sunucudan gerçekten gelenle eşleşecek şekilde belgeleri yazmak size kalmıştır.
DocumentFile sınıfınızı bir arayüz olarak değiştirmenizi, kurulum kodunu normal bir fonksiyon tanımına taşımanızı ve sadece şöyle çağırmanızı tavsiye ederim:
setup(doc);
C#'tan gelen biri için sadece bir fonksiyon tanımının ortada duruyor olması garip gelebilir, ama size temin ederim ki bu tamamen normal ve bu tür bir durumu yönetmenin oldukça standart bir yoludur.
