Show CMS content in table based on pricing plan field value

I’m having trouble with
Trying to display content from CMS in a table based on a selection made by a user on a form when they’ve signed up to a pricing plan. They have 3 options to select from which will serve them up a different plan. Is this possible? Do I need to define the items in the CMS by field key?

Working in
Wix Editor

What I’ve tried so far
My code so far is below. Thanks in advance!

import wixData from 'wix-data';

$w.onReady(function () {
$w('#table1').onClick(async (event) => {
    try {
        // Assuming the selected field value is stored in a variable named selectedFieldValue
        let selectedFieldValue = "weight"; // Replace with actual logic to get the selected field value

        // Query the CMS collection based on the selected field value
        let results = await wixData.query("Starter Eating Female Under 75kg")
            .eq("weight", selectedFieldValue) // Replace 'fieldKey' with the actual field key
            .find();

        // Update the table rows with the query results
        $w('#table1').rows = results.items.map(item => {
            return {
                "column1": item.meal, // Replace 'field1' with actual field keys
                "column2": item.eat, // Replace 'field2' with actual field keys
                "column3": item.amount, // Replace 'field1' with actual field keys
                "column4": item.eatLess, // Replace 'field2' with actual field keys
                "column5": item.avoidEating, // Replace 'field1' with actual field keys
                "column6": item.exercisedBeforeMealAdd, // Replace 'field2' with actual field keys
                "column7": item.amount1, // Replace 'field1' with actual field keys
       
                // Add more columns as needed
            };
        });
    } catch (error) {
        console.error("Error fetching data from CMS:", error);
    }
});
})
1 Like

Hi Linda,

From a glance, your code looks incomplete. Is your collection name correct? This reads as the plain text, not the camel case name associated to your collection name.

The collection name would usually look something like “startedEatingFemaleUnder75Kg” if that’s the actual collection name.

You should add a console.log after this line to make sure your query is working:
console.log(results?.items, 'check results')

I also don’t see anywhere in the code where this variable changes:

You have this variable set to a .eq weight field key. Is the field type a string (text) or number here?

If your results.items returns an array with a length greater than 0, you would then update your table rows like this as shown in the documentation here.

I also want to ask why you’re using an event handler when the table is clicked to fetch your data? Why not use a variable and fetch the entire database when the page loads, then render the table rows based on a button click event? That way you don’t keep refetching data when it’s only needed once. If the data is constantly being updated, then you may need to update your query based on certain events to avoid stale data but this doesn’t sound like a CRUD operation to me.

Hi, @Linda_Oldfield !!

Trying to solve everything at once is hard :innocent: , so let’s break the problem down. To start, I think it’s best to perfectly implement just the part that retrieves the selected values from the form! The same applies even if your code was written by AI — asking an AI for a complex specification all at once often confuses it and leads to incorrect code. :upside_down_face: Break the problem into steps and ask the AI about each step that will increase your chances of success. :laughing: Also, I’m curious — why are you clicking the table? :slightly_smiling_face:

Thank you for your replies. You’re right that I don’t want it onClick, I want it onLoad instead, but when I try and remove it I get an error! Essentially I want the page to load in whatever format (it doesn’t need to be table), and display content from the CMS based on the option they selected for their weight range when they first signed up via the Pricing Plan form (there are 4 options to choose from, which I have built in the CMS in their own collections). What base code would I use for this to call the users input into the form, and then serve up the relevant content? And would this be best in a table, repeater, or something else? Sorry, new starter here :smiley:

I see. :slightly_smiling_face: The reason you get an error when trying to remove .onClick() is probably because you’re using await—and await needs to be inside an async function. But that’s not really a big issue. From what we’ve discussed so far, it seems that the user’s current weight information is already stored in some collection, and the first thing we need to do is retrieve it. It’s possible to pull the weight data from that collection, but the key point is how that data is associated—specifically, it must be saved together with something like the user’s ID. :innocent:

Can you provide me with your collection names so I can build a demo for you? To @onemoretime’s point, did you associate their weight to the user ID via wix members area? Without being a website contributor I cannot give you the complete code since you will need to make changes but this is what I would do:

  1. Create a backend dataProvider.web.js file to perform your queries – you can do this from the frontend but performance will be better to do this here.
  2. Structure your page code to fetch your queries on load. Do NOT make $w.onReady an async function. Rather, call an async init() function instead, this will also improve performance.
  3. Create a let allData variable in the root of your page code (underneath your import statements)
  4. Use the init function to assign the data queries items to your allData variable (no longer need to refetch your data now)
  5. Populate a table (or repeater), your choice. If you have overflow x and are mobile friendly, I would recommend a table.

Here is an example of what your dataProvider.web.js can look like – note that I changed the code so to accomodate large databases with over thousands of items:

import { Permissions, webMethod } from 'wix-web-module';
import wixData from 'wix-data';
const defaultCollectionName = 'yourCollectionName'

// return more than 1000 if needed by date range
export const getAllUserWeightsDataByDateRange = webMethod(Permissions.Anyone, async (dateRange, collectionName = defaultCollectionName) => {
    const { startDate, endDate } = dateRange
    let query = await wixData.query(collectionName).ge('_createdDate', new Date(startDate)).lt('_createdDate', new Date(endDate)).isNotEmpty('division').limit(1000).find()
    let allItems = query.items
    while (query.hasNext()) {
        query = await query.next();
        allItems = allItems.concat(query.items)
    }
    return allItems
})

// returns all unfiltered
export const getAllUserWeightsInDb = webMethod(Permissions.Anyone, async (collectionName = defaultCollectionName) => {
    let query = await wixData.query(collectionName).limit(1000).find()
    let allItems = query.items
    while (query.hasNext()) {
        query = await query.next();
        allItems = allItems.concat(query.items)
    }
    return allItems
})

// filter by weight => is weight a number or string?
export const getAllByWeight = webMethod(Permissions.Anyone, async (weight = 160, collectionName = defaultCollectionName) => {
    let query = await wixData.query(collectionName).eq('weight', weight).limit(1000).find()
    let allItems = query.items
    while (query.hasNext()) {
        query = await query.next();
        allItems = allItems.concat(query.items)
    }
    return allItems
})

Also note, that when you call this on the front end, if this is a members area website and you already have their weight, then you would need to get their weight first by their member ID, then you can call the “getAllByWeight” function and pass the weight prop. If these are 4 different collections you need to query, you should use a await.Promise.all() as well.

Thank you both for your quick replies. The collection ID is StarterEatingFemaleUnder75kg. The challenge I’m having is the collection is just the content I want to to display (there’ll be four options for this), and I need it to look at that users profile from when they signed up to a Pricing Plan (I’ve used the customisable forms to collect extra information at checkout) to determine what option they selected on their form for ‘Weight Range’ and ‘Gender’ (see screenshots below). I can’t see where this information is stored but it must be somewhere in the Members Area that I can pull from, and I don’t want to have to load it into the CMS manually if I can avoid it.

Hmm :slightly_smiling_face: , for now, I think this issue won’t move toward a resolution unless you first identify which collection your additional information is being stored in. So please start by finding that. It’s probably in one of the form-related collections, so take a look there. Alternatively, it might be stored in the PrivateMembersData collection. :raising_hands: