Skip to main content

Hi folks



I have two tables: One is called “Products” the other is called “Product Components”. As you can imagine there is a (1:N) link between them, so a Product can have multiple Components. A Component has a single Product.



Here is what I am trying to do: I need to fetch all Components for a Product.



I have a RecordQueryResults called “allComponents”. product.id contains the Product I’m searching for. Here is my code:



let components = allComponents.records.filter(record => {


(record.getCellValue(“Product”).map(x => x.id).includes(product.id)) });



After this, if I check components.length I will get zero. It is an empty array.



I tried debugging using console.log inside my filter callback:



let components = allComponents.records.filter(record => {


console.log(record.getCellValue(“Product”).map(x => x.id).includes(product.id));


(record.getCellValue(“Product”).map(x => x.id).includes(product.id)) });



The results are: whenever a Product matches product.id I get TRUE; when it doesn’t I get FALSE. Therefore it would appear that the filter is working.



However, “components” is always an empty array…



Can anyone help me figure this out?


Thanks


Alex

Welcome to the Airtable Community!





Your filter function doesn’t actually return anything. Your filter function checks if the cell value include the product id, but doesn’t actually return the value for the filter to use.



Option 1: Remove the curly braces. When there is only a single statement in the arrow function, the value of the statement is returned.



let components = allComponents.records.filter(record => 

record.getCellValue(“Product”).map(x => x.id).includes(product.id)

);



Option 2: Have an explicit return statement in the arrow function



let components = allComponents.records.filter(record => {

let result = (record.getCellValue(“Product”).map(x => x.id).includes(product.id))

return result

});



Note that the above options will throw an error if you have a component record that doesn’t belong to any products.



Option 3 (my preferred method): Get the records from the other side.


Since you state that product.id is the id of the product, I assume that product is the record for the product. I also assume that you know the name of the field with the linked components.



let componentsLinkedValue = product.getCellValue("Components")

let components = componentsLinkedValue.map(obj =>

allComponents.getRecord(obj.id)

)



If there is a possibility that there are no linked components you will also need to include a check for that.


Welcome to the Airtable Community!





Your filter function doesn’t actually return anything. Your filter function checks if the cell value include the product id, but doesn’t actually return the value for the filter to use.



Option 1: Remove the curly braces. When there is only a single statement in the arrow function, the value of the statement is returned.



let components = allComponents.records.filter(record => 

record.getCellValue(“Product”).map(x => x.id).includes(product.id)

);



Option 2: Have an explicit return statement in the arrow function



let components = allComponents.records.filter(record => {

let result = (record.getCellValue(“Product”).map(x => x.id).includes(product.id))

return result

});



Note that the above options will throw an error if you have a component record that doesn’t belong to any products.



Option 3 (my preferred method): Get the records from the other side.


Since you state that product.id is the id of the product, I assume that product is the record for the product. I also assume that you know the name of the field with the linked components.



let componentsLinkedValue = product.getCellValue("Components")

let components = componentsLinkedValue.map(obj =>

allComponents.getRecord(obj.id)

)



If there is a possibility that there are no linked components you will also need to include a check for that.




Thank you! #1 worked like a charm. I will study #3 further as it is indeed a much more elegant solution.




Thank you! #1 worked like a charm. I will study #3 further as it is indeed a much more elegant solution.


@kuovonne I have a question about your Option #3


I do have Product but it seems it is not a Record.


I have read from another Object called Quotes a cell called “Products” where we can select multiple Products in a Quote, but it seems the returned values are not records, but a collection of objects with Id and Name, but not all the Cells/Properties…



Here is what I did:



let products = currentQuote.getCellValue(“Products”)


for (let product of products) {


console.log(product.name) // this works fine


console.log(produc.id) // this works fine


console.log(product.getCellValues(“Product Components”)) // this does not work


}



Do you see anything I could do to actually get the Product Components from the Product Table linked attribute as you suggested?


At this time the only thing that occurs to me is reading the Product Table - but again I would have to use filter to find the correct product, so it would be basically the same as using Option #1 :winking_face:



Please, let me know if you have any other suggestions 🙂


Thanks!!!


@kuovonne I have a question about your Option #3


I do have Product but it seems it is not a Record.


I have read from another Object called Quotes a cell called “Products” where we can select multiple Products in a Quote, but it seems the returned values are not records, but a collection of objects with Id and Name, but not all the Cells/Properties…



Here is what I did:



let products = currentQuote.getCellValue(“Products”)


for (let product of products) {


console.log(product.name) // this works fine


console.log(produc.id) // this works fine


console.log(product.getCellValues(“Product Components”)) // this does not work


}



Do you see anything I could do to actually get the Product Components from the Product Table linked attribute as you suggested?


At this time the only thing that occurs to me is reading the Product Table - but again I would have to use filter to find the correct product, so it would be basically the same as using Option #1 :winking_face:



Please, let me know if you have any other suggestions 🙂


Thanks!!!


Ah, you have the value from a linked record field, not the actual product record itself. The linked record field value contains the id an “name” of the record, but no additional information, and now way to directly get any cell values.



It sounds like you are starting from the sQuotes] table and need to get eComponents] which are two tables away, without actually need to get the product record itself.



In this case, I recommend going with option 1.


Ah, you have the value from a linked record field, not the actual product record itself. The linked record field value contains the id an “name” of the record, but no additional information, and now way to directly get any cell values.



It sounds like you are starting from the tQuotes] table and need to get gComponents] which are two tables away, without actually need to get the product record itself.



In this case, I recommend going with option 1.


Awesome, thank you! :winking_face:


Reply