In Angular find an object based on the Id provided in the main object

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)
    });
  }
}

Upvotes: 0

Views: 900

Answers (2)

SomeStudent
SomeStudent

Reputation: 3048

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);
}

Working JS Fiddle of just the core logic: https://www.typescriptlang.org/play?ssl=36&ssc=17&pln=39&pc=44#code/JYOwLgpgTgZghgYwgAgCpwB7IN4FgBQyyA+sACYBcyAzmFKAOYFFiYBycAthFbfSE0LJgDWgCU4kKiACunAEbRmyBKLASpyWQqVDqajTy1zFUAgF8CBUJFiIUABSgB7MjIRgcy0pRp1GygAOLm4eHNy8-gLKrBgAkr58AfiW+AQIziC0yMGu7mDUyFROeR4A2gC6yAC8yJUA3OmZ2bEQhVToGJU1dRWN+ABucFAqzgqgEGRxkJztyHAgAJ7dtQ1W+BlZnoHOgTIANpIQACKScD0AFACUNQB8XkK5oQUAdHvUABYX2D5UAOQAeRAED+ABociF8uEjH9oWDkLEEv9OkCQeYrv0iE98tQ3jJPt9fsg-qgAO7OeHYsJcGHQtDk+GI3wkzBkino-oxTBtPEEn7kZGYVGM9g0wVYOnC8EicRHKgARnBqllmgATOD9CqjABmDlcjA895ffnMzpskUYaHi5B083Sgxy5CKlQOtUa106jnICzrTbZDLjYGoZwMCBgD7QS43ar3PBCIhY3YHI6nVjXTnxhMB+QTKYzQq1KmvThwQIXLAxh4J6vIfZhiGlMAlQLQMDANo9E1UDAvHzgotW5A9gc08FM7svJnIcw9DCYmtEOueREzHqtXEwUBkC4ALzuyB3vfINVqPaZGPWC6IwBgFxXEE4NzjV4TS4RmGbrfbBZw3szL+rWJB3vThJ1FbhkFBZQAJrGV1EdECXjgwxwWgmCsw9KhEOVeDIFQ-90M1XCjEQojDD-dDpzXTBpgfDMYLfYBV1qbAXjYotPygNs2nBNiwIwTjuOocx5xfKAwxkKAQGEGZRJrVI0OrcSwEk6TZH2fY5OrdEXk3fZbHLfcsAAQmqWp1P2C8Ul9ZpPGzCYAEEQDIJwbCjfdn1GQMIGDUNw2gdNlD9Zw6xefYQwuezgTzB9qCshSNjGHNgSclz+DAQL8CAA

Upvotes: 1

Hossein Sabziani
Hossein Sabziani

Reputation: 3495

see this example:

let Product:any[]=[];
Product.push({_id:1,productName:'name1',taxId:101})
Product.push({_id:2,productName:'name2',taxId:102})

let Tax:any[]=[];
Tax.push({_id:1,taxName:'taxName1',taxRate:201})
Tax.push({_id:2,taxName:'taxName2',taxRate:202})


let findtaxID=102; //taxId to be found

let ProductResult=Product.find(x => x.taxId == findtaxID);
let TaxtResult=Tax.find(x => x._id == ProductResult['_id']);

let finalResult={_id:ProductResult['_id'],productName:ProductResult['productName'],taxId:ProductResult['taxId'],
taxName:TaxtResult['taxName'],taxRate:TaxtResult['taxRate']}

console.log(finalResult)

and the result:

enter image description here

Hope this helps!

Upvotes: 0

Related Questions