Issue
Let's say I have 2 Objects
Product
_id
productName
taxId
Tax
_id
taxName
taxRate
Using Angular I want to be able to use the taxId
in Product
and find the corresponding taxName
and taxRate
and result the final object like this.
_id
productName
taxId
taxName
taxRate
I suppose the tax fields could be nested if needed.
EDIT: Adding the code as requested reducing unnecessary parts.
product.ts
export interface Product {
_id: string
productName: string
taxId: string
}
tax.ts
export interface Tax {
_id: string
taxName: string
igstRate: number
cgstRate: number
sgstRate: number
}
the service.
export class TaxService {
private productUrl = Url + 'products';
private taxUrl = Url + 'taxs';
constructor(private httpClient: HttpClient) {}
getAllPdt(): Observable<Product[]> {
return this.httpClient.get<Product[]>(this.productUrl);
}
getAllTax(): Observable<Tax[]> {
return this.httpClient.get<Tax[]>(this.taxUrl);
}
getOneTax(id: string): Observable<any> {
return this.httpClient.get(this.taxUrl + '/find/' + id);
}
}
the component is Updated as @SomeStudent answer
import { Component, OnInit } from '@angular/core';
import { TaxService } from '../services/tax.service';
import { Tax } from '../interfaces/tax';
import { Product } from '../interfaces/product';
import { combineLatest } from 'rxjs';
@Component({
selector: 'app-tax',
templateUrl: './tax.component.html',
styleUrls: ['./tax.component.css'],
})
export class TaxComponent implements OnInit {
taxs: Tax[] = [];
products: Product[] = [];
combinedItems : any[] = [];
constructor(public taxService: TaxService) {}
ngOnInit(): void {
combineLatest([
this.taxService.getAllPdt(),
this.taxService.getAllTax(),
]).subscribe(([pdts, taxes]: [Product[], Tax[]]) => {
if (taxes && pdts) {
this.products = pdts;
this.taxs = taxes;
this.combinedItems = this.products
.map((x) => {
let productProperties = ({
_id: x._id,
productName: x.productName,
taxId: x.taxId,
} = x);
let taxItem = taxes.find((z) => z._id == x.taxId);
if (taxItem) {
let taxProperties = ({
taxName: taxItem.taxName,
igstRate: taxItem.igstRate,
cgstRate: taxItem.cgstRate,
sgstRate: taxItem.sgstRate,
} = taxItem);
let item = { ...productProperties, ...taxProperties };
console.log(item);
return item
}
return null;
})
.filter((x) => x !== null);
}
console.log(this.combinedItems)
});
}
}
Solution
First thing first, this is not related to angular, this is a JS/TypeScript question. Angular is a front end framework. Below is some very rough, big picture pseudo-ish code. The biggest part here is the ...
operator. This is called a spread operator. What it does is it "spreads" all of the properties of the object we are working with, we can use it to reduce the amount of syntax we write.
A bit more reading: https://www.freecodecamp.org/news/javascript-object-destructuring-spread-operator-rest-parameter/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
That said, if you have two separate collections of Product and Tax:
myProducts: Product[] = [];
myTaxes: Tax[] = [];
//populate your products and tax arrays however you do
Then what you can do is:
let myProduct = this.myProducts.find(x => x._id == productId);
let myTaxForProduct = this.myTaxes.find(x => x._id == myProduct.taxId);
let subPartsOfMyTax = taxId, taxName, taxRate } = myTaxForProduct;
let mySpecialObject = {
...myProduct, ...subPartsOfMyTax
}
You can try the above, or something similar to it, in your browser's console window. type the following things in this order
let myProduct = {id: 1, t: 'b', n: 'c'}
let myTax = {id: 2, tax: 'alot', taxId: 'c'}
let subPartsOfMyTax = {tax, taxId} = myTax
{...myProduct , ...subPartsOfMyTax }
End result of the above MVP is: {id: 2, t: 'b', n: 'c', tax: 'alot', taxId: 'c'}
which is generally speaking the same general concept of what you want to achieve.
Edit: Now that you've posted the code.
Your component.ts file
combinedItems : any[] = [];
ngOnInit() {
combineLatest([this.taxService.getAllPdt(),
this.taxService.getAllTax()])
.pipe()
.subscribe(([pdts, taxes] : [Product[], Tax[]) => {
if(taxes && pdts) {
this.products = pdts;
this.taxs = taxes;
combinedItems = this.products.map(x => {
let productProperties = {_id: x._id, productName: x.productName, taxId: x.taxId } = x;
let taxItem = taxes.find(z => z._id == x.taxId);
if(taxItem) {
let taxProperties = {
taxName: taxItem.taxName ,
igstRate: taxItem.igstRate,
cgstRate: taxItem.cgstRate,
sgstRate: taxItem.sgstRate
} = taxItem;
let item = {...productProperties, ...taxProperties};
return item;
}
return null;}
}).filter(x => x !== null);
}
Answered By - SomeStudent
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.