Uncaught TypeError using Attributes API

Hello, I’m using the Attributes API to grab external data and bring it into Webflow using CMS Load.

I’ve been following along with the youtube video [https://www.youtube.com/watch?v=VgI8rf9mbH4](https://Attributes API Tutorial Part 1) and got to the very end, but I keep hitting an error related to t.querySelector is not a function.

Page: [test-POS Catalog](Test page)

I want some help with what I can do to remedy this issue.

Here is the code I have on the page.

window.fsAttributes = window.fsAttributes || []
window.fsAttributes.push(['cmsload', async (listInstances) => {
    console.log('cmsload Successfully loaded!')

    const [listInstance] = listInstances //defines cms list being used
    const [item] = listInstance.items //defines single item from reference list
    const itemTemplate = item.element //defines template using single item
		
    const cards = await fetchItems() //grabs data from external api
    listInstance.clearItems() //removes placeholder items

    const newItems = cards.map((card) => newItem(card, itemTemplate))
    await listInstance.addItems(newItems)
}])

const fetchItems = async () => {
    try {
        const res = await fetch('my_api')
        const data = await res.json()

        return data
    } catch(error) {
        return []
    }
}

const newItem = (item, template) => {
    const { image_url, name, number, inventory, type } = item
    const clone = template.cloneNode(true)
    const img = clone.querySelector('[data-element="image"]')
    const title = clone.querySelector('[data-element="title"]')
    const cardType = clone.querySelector('[data-element="type"]')
    const cardInventory = clone.querySelector('[data-element="inventory"]')
    const cardNumber = clone.querySelector('[data-element="number"]')

    if(image_url){
        if(img) {
            clone.querySelector('[data-element="no-image"]').classList.add('display-none')
            img.src = image_url
        }
    } else {
        if(img) img.classList.add('display-none')
    }
    if(title) title.textContent = name
    if(cardType) cardType.textContent = type
    if(cardInventory) cardInventory.textContent = inventory
    if(cardNumber) cardNumber.textContent = number

    return newItem
}

Hey @bradley.brazis! The issue comes from here, you are returning the newItem function instead of the cloned element

We need to return the clone as this is the HTML elements addItems is expecting

  const newItem = (item, template) => {
    const { image_url, name, number, inventory, type } = item;
    const clone = template.cloneNode(true);

    const img = clone.querySelector('[data-element="image"]');
    const title = clone.querySelector('[data-element="title"]');
    const cardType = clone.querySelector('[data-element="type"]');
    const cardInventory = clone.querySelector('[data-element="inventory"]');
    const cardNumber = clone.querySelector('[data-element="number"]');

    if (image_url) {
      if (img) {
        clone.querySelector('[data-element="no-image"]').classList.add('display-none');
        img.src = image_url;
      }
    } else {
      if (img) img.classList.add('display-none');
    }

    if (title) title.textContent = name;
    if (cardType) cardType.textContent = type;
    if (cardInventory) cardInventory.textContent = inventory;
    if (cardNumber) cardNumber.textContent = number;

    return clone;
  };

This is the result :wink:

1 Like

Awesome, thank you so much! I kinda figured I missed something!

No worries! Happy to help :muscle:

1 Like