I'm facing undefined data outside of subscribe, but it's getting inside of subscribe. I know, it's because of the Observable behavior. But how can I resolve this?
edit.ts
ngOnInit(): void {
let product
this.productId = this.route.snapshot.paramMap.get('id')
if (this.productId) {
this.productService
.getProductDetails(this.productId)
.subscribe((response) => {
product = response.data
console.log(product)
})
}
console.log(product)
this.form = new FormGroup({
productName: new FormControl(null, Validators.required),
type: new FormControl(null, Validators.required),
model: new FormControl(null)
})
}
service.ts
getProductDetails(id: string) {
return fromFetch(`http://localhost:3000/product/${id}`).pipe(
switchMap((response) => {
if (response.ok) {
return response.json()
} else {
return of({ error: true })
}
})
)
}
Here, I want to access the product outside of subscribe.
CodePudding user response:
so the subscribe
part will execute asynchronously, whereas the console.log
outside the subscribe is synchronous. So there is no way to access the output of subscribe, outside of the subscribe. instead, move the code inside the subscribe.
ngOnInit(): void {
let product
this.productId = this.route.snapshot.paramMap.get('id')
if (this.productId) {
this.productService
.getProductDetails(this.productId)
.subscribe((response) => {
product = response.data
console.log(product)
this.form.patchValue(product);
})
}
this.form = new FormGroup({
productName: new FormControl(null, Validators.required),
type: new FormControl(null, Validators.required),
model: new FormControl(null)
})
}
Reference to understand synchronous and asynchronous in javascript
CodePudding user response:
You don't necessarily need to access it outside of the subscribe handler, you can just build the form when the product becomes available:
ngOnInit(): void {
this.route.paramMap
.pipe(
filter((map) => !!map.get('id')),
// only if you still need this as a property
tap((productId) => (this.productId = productId)),
switchMap((productId) =>
this.productService.getProductDetails(productId)
),
map((response) => response.data)
)
.subscribe((product) => this.buildProductForm(product));
}
buildProductForm(product: any): void {
this.form = new FormGroup({
productName: new FormControl(null, Validators.required),
type: new FormControl(null, Validators.required),
model: new FormControl(null),
});
}