Reputation: 17
I am trying to query my database for a list of templates. I want to print these checkout templates on my frontend view but I get returned undefined when I call my service class.
checkout.component.ts:
export class CheckoutComponent implements OnInit, OnDestroy {
templates: Template[] = [];
constructor(public checkoutService: CheckoutService) {}
ngOnInit(): void {
try {
const templates = this.checkoutService.getTemplates();
console.log(JSON.stringify(templates))
} catch (err) {
console.log(err)
}
}
// ...
}
When I console.log the templates from the checkout service, it comes out as undefined. checkout.service.ts:
export class CheckoutService {
private url = "http://localhost:3000/checkout";
constructor(private http: HttpClient, private router: Router) {}
getTemplates() {
this.http.get<{ templates: Template[] }>(this.url).subscribe(data => {
return data;
})
}
}
This is the http://localhost:3000/checkout endpoint on the backend
(THIS CORRECTLY RETURNS THE DATA):
router.get("", (req, res, next) => {
var templates = [];
var realTemps = [];
const token = req.headers.authorization.split(" ");
const decoded = jwt.verify(token[1], 'secretkey');
decodedFactoryId = decoded.factoryId
Template.findAllByFactoryId(decodedFactoryId)
.then((results) => {
for (var i = 0; i < results.length; i++) {
// THIS IS AN AVOIDABLE LOOP,
// TODO: quadratic time must be prevented by correctly formatting the data
for (var j = 0; j < results.length; j++) {
if (results[i][j].id) {
templates.push(results[i][j].id)
}
}
}
}).then(() => {
// Promise.all
return Promise.all(templates.map(template =>
Template.findByTemplateId(template).then(result => {
console.log("here is the result: " + JSON.stringify(result[0]))
realTemps.push(result);
})
));
})
.then(() => {
return realTemps;
})
})
When I try to console.log the getTemplates() code:
getTemplates(): Observable<{templates: Template[]}> {
console.log( JSON.stringify(this.http.get<{templates: Template[] }>(this.url)))
return this.http.get<{templates: Template[] }>(this.url)
}
I get this printed in the console, instead of the data:
{
"_isScalar": false,
"source": {
"_isScalar": false,
"source": {
"_isScalar": false,
"source": {
"_isScalar": false
},
"operator": {
"concurrent": 1
}
},
"operator": {}
},
"operator": {}
}
Upvotes: 0
Views: 1043
Reputation: 1079
Your method on your service doesn't return anything. That is why you're getting undefined.
The problem is that you are defining the observable and immediately subscribing to it in your service. The return statement inside your subscribe method is relative to the subscribe callback, not your service, so it doesn't do anything here.
Instead, what you need to do is return the observable from your service method like this:
getTemplates(): Observable<{templates: Template[]}> {
return this.http.get<{templates: Template[] }>(this.url)
})
And then subscibe to it in the ngOnInit method in your component like this:
export class CheckoutComponent implements OnInit, OnDestroy {
templates: Template[];
constructor(public checkoutService: CheckoutService) { }
ngOnInit() {
this.checkoutService.getTemplates().subscribe(({templates}) => this.templates = templates)
}
You also don't need to explicitly state the return type of the ngOnInit, nor do you need to wrap this in a try/catch. Error handling is a bit different with observables.
Upvotes: 1