I've got an Angular (v12) service, holding API calls through httpClient
requests, where I also would like to put a method to check if an object already exists at backend level (before it reaches it, but of course there also is a safety there).
So what I do is trigger the http get, then pass the answer to a method to enrich it and store the result in a private attribute (visaDatesList
) which is supposed to hold the list of my objects.
That list is being fed while my component calls the getAllVisaDates()
method, which I was able to confirm using a console.log...
Below, part of my service's code:
@Injectable({
providedIn: 'root'
})
export class VisasService{
private visaDatesList: VisaDate[] = [];
constructor(private httpClient: HttpClient) {}
public getAllVisaDates(): Observable<VisaDateAnswer> {
return this.httpClient
.get(`${this.baseUrl}/visa-dates`, { observe: 'response' })
.pipe(map(this.getVisaDates));
}
public checkIfVisaDoesNotAlreadyExists(visa: VisaDate): boolean {
console.log(this.visaDatesList);
let matchedYear = false;
let matchedMonth = false;
for (const entry of this.visaDatesList) {
for (const [key, value] of Object.entries(visa)) {
if (key === 'visaYear' && value === visa.visaYear) {
matchedYear = true;
}
if (key === 'visaMonth' && value === visa.visaMonth) {
matchedMonth = true;
}
if (matchedMonth && matchedYear) {
return false;
}
}
matchedYear = false;
matchedMonth = false;
}
return true;
}
private getVisaDates(res: HttpResponse<VisaDate[]>) {
const header = res.headers.get('x-visaapp-params');
const data = res.body;
this.visaDatesList = res.body as VisaDate[];
return { size: header, data, status: res.status };
}
}
As I said, the point here, in my getVisaDates()
method, using a console.log, I can see that my list visaDatesList is properly fed.
Problem lies in the checkIfVisaDoesNotAlreadyExists()
method. For some reason the list is seen as empty when another component calls the service, even if my previous console.log (in the getVisaDates()
) was showing datas... If I'm not wrong, services are supposed to be Singletons, and storing data to be shared between components is supposed to be the proper way of using them ?
Maybe I am missing something obvious here but I can't have this working, any idea/help ?
Thanks!
CodePudding user response:
You're losing the context of this
keyword in getVisaDates()
since it's passed as a callback with it's own scope. So when you're attempting this.visaDatesList = res.body as VisaDate[];
it isn't necessarily assigning the value to the class member variable visaDatesList
.
You'd either need to use bind(this)
return this.httpClient
.get(`${this.baseUrl}/visa-dates`, { observe: 'response' })
.pipe(map(this.getVisaDates.bind(this)));
Or use arrow function
return this.httpClient
.get(`${this.baseUrl}/visa-dates`, { observe: 'response' })
.pipe(map((res: HttpResponse<VisaDate[]>) => this.getVisaDates(res)));
You could find more info about using this
keyword in callbacks here.