How do i put recieved backend values from query into elements in form

Hi

I’ve written my backend code which is working fine as i can see the correct values in the consol log on my form.

what i cannot figure out is how do i get the values of the consol log into my elements on my form? (element names as below) this is how i thought my front end should look but it errors says item undefined

FRONT END

import wixData from ‘wix-data’;
import {populateNutrients} from ‘public/new-file.js’

$w.onReady( function () {
populateNutrients(“MyFoods”,“Banana (Large)”)
$w(’ #protein1Text ‘).text = item.protein.toString();
$w(’ #carbohydrate1Text ‘).text = item.carbs.toString();
$w(’ #fat1Text ‘).text = item.fat.toString();
$w(’ #calories1Text ').text = item.calories.toString();
});

BACKEND

import wixData from ‘wix-data’;

export function populateNutrients (collectionName,valueField) {
wixData.query(collectionName)
.eq(“foodType”,valueField)
.find()
.then( (results) => {
let items = results.items;
let item = items[0];
let measurement = item.measurement;
let protein = item.protein
let carbohydrates = item.carbs
let fat = item.fat;
let calories = item.calories;
console.log(measurement,protein,carbohydrates,fat,calories)
} )
. catch ( (err) => {
let errorMsg = err;
console.log(errorMsg);
})
}

1 Like

Greetings,

There isn’t any need to run a backend function for this kind of data that is not sensitive information. Putting the function in the page code is preferable.

$w.onReady(function () {
    populateNutrients("MyFoods","Banana (Large)")
});

export function populateNutrients (collectionName,valueField) {
    wixData.query(collectionName)
    .eq("foodType", valueField)
    .find()
    .then((results) => {
         let items = results.items;
         let item = items[0];
        $w('#protein1Text').text = item.protein.toString();  
        $w('#carbohydrate1Text').text = item.carbs.toString();  
        $w('#fat1Text').text = item.fat.toString();  
        $w('#calories1Text').text = item.calories.toString();   
     })
    .catch((err) => {
         let errorMsg = err;
         console.log(errorMsg);
    })
} 

Hi. the issue is its a huge page and there are 48 of these drop downs and the page load times are horrific. i was looking to use the backend in order to maybe speed the page load times up and not have to repeat this code 48 times??

its basically a diet creator and in the drop down a food is selected which in turn returns the nutrient values for the selected food.

what’s your thoughts?

I got a little further with the below as a backend function however i need the $w(“#measurement3Text”).text and other elements to be triggered via front end call how would i do that? else ill need to write 48 back end calls!! which is kinda useless too lol

export function populateNutrientsfood3 (collectionName,valueField) {
wixData.query(collectionName)
.eq(“foodType”,valueField)
.find()
.then( (results) => {
let items = results.items;
let item = items[0];
let measurement = item.measurement;
let protein = item.protein
let carbohydrates = item.carbs
let fat = item.fat;
let calories = item.calories;
$w(“#measurement3Text”).text = item.measurement;
$w(“#protein3Text”).text = item.protein.toString();
$w(‘#carbohydrate3Text’).text = item.carbs.toString();
$w(‘#fat3Text’).text = item.fat.toString();
$w(‘#calories3Text’).text = item.calories.toString();
console.log(measurement,protein,carbohydrates,fat,calories)
} )
. catch ( (err) => {
let errorMsg = err;
console.log(errorMsg);
})
}

@fraser You are expecting the back-end call to speed things up, but I don’t see any proof that it is any quicker. The main challenge here is to make sure the data has been returned before assigning it to the text elements. The code that I put in the last post does do that. Javascript code executes asynchronously, that is, it’s onto the next line even if the previous line(s) have not fully executed. With a query, there is a call to the server to fetch some data. In the meantime, the rest of the function’s code continues to execute unless you code for it. That’s what the .then is all about. There is a also asynch await .

But … I hear you. With 48 dropdowns, you have a challenge on your hands to get decent response times. Maybe it would help to see the page to get a better idea of what you’re dealing with.

Hi Tony, thanks for taking an interest mate! it sure is a challenge sometimes im seeing page load times of 4 mins!!! crazy stuff

never shared the site before not sure if its how you do it but the link is below. the 2 killer pages are

New diet creator = where the Administrator creates a brand new diet for a client

Diets editor (ID) = where a created diet can be amended. Essentially a dynamic page reading data from database and populating fields

these are 2 mega pages and hold a lot of data as you will see.

http://wix.to/3ECJAPQ

let me know if the link works

Cheers

Fraser

Hey Fraser,

Can’t find the pages you’re referencing, but I would recommend two things:

  1. use .limit() as well as results[0]
  2. See if you can use a loop somehow so that you only execute the query once instead of for each iteration.

@skmedia Yeah been trying the loop however its tricky!!! this backend code below for example is the same one that i need to use to populate all 48 drop downs however the text box numbers change for each drop down.

For example the code below is a bespoke code for drop down 3 of 48 hence named it poulate Nutirents3 i dont want to do that id like to call this one back end code from 48 different drop downs but cant figure out how to manage the text input fields!

Can you help?

BACKEND

export function populateNutrientsfood3 (collectionName,valueField) {
wixData.query(collectionName)
.eq(“foodType”,valueField)
.find()
.then( (results) => {
let items = results.items;
let item = items[0];
let measurement = item.measurement;
let protein = item.protein
let carbohydrates = item.carbs
let fat = item.fat;
let calories = item.calories;
$w(" #measurement3Text “).text = item.measurement;
$w(” #protein3Text ").text = item.protein.toString();
$w(’ #carbohydrate3Text ‘).text = item.carbs.toString();
$w(’ #fat3Text ‘).text = item.fat.toString();
$w(’ #calories3Text ').text = item.calories.toString();
console.log(measurement,protein,carbohydrates,fat,calories)
} )
. catch ( (err) => {
let errorMsg = err;
console.log(errorMsg);
})
}

FRONT END

export function food1Dropdownlist_change(event) {
populateNutrientsfood1(“MyFoods”,$w(“#food1Dropdownlist”).value)
}

I felt sure i could maybe do something like this to create a loop?? but doesn’t seem to populate the text fields on the form

BACKEND

export function populateNutrientsfood (collectionName,valueField,measurementValue ProteinValue,carbohydrateValue,fatValue,caloriesValue) {
wixData.query(collectionName)
.eq(“foodType”,valueField)
.find()
.then( (results) => {
let items = results.items;
let item = items[0];
let measurement = item.measurement;
let protein = item.protein
let carbohydrates = item.carbs
let fat = item.fat;
let calories = item.calories;
measurementValue = item.measurement;
proteinValue = item.protein.toString();
carbohydrateValue = item.carbs.toString();
fatValue= item.fat.toString();
calorieValue = item.calories.toString();
console.log(measurement,protein,carbohydrates,fat,calories)
} )
. catch ( (err) => {
let errorMsg = err;
console.log(errorMsg);
})
}

FRONT END

export function food1Dropdownlist_change(event) {
populateNutrientsfood(“MyFoods”,$w(“#food1Dropdownlist”).value,$w(" #measurement3Text “).text,$w(” #protein3Text ").text,$w(’ #carbohydrate3Text ‘).text,$w(’ #fat3Text ‘).text,$w(’ #calories3Text ').text )

@tony-brunsman Just on that Javascript code executes asynchronously, that is, it’s onto the next line even if the previous line(s) have not fully executed.

Im still not fully sure on the correct way to write Java script, i mean i get by but i know the tabs and the lines that come down create your loops and close functions but would like to learn a bit more obviously.

Any whee i can read some simple stuff on that so my codes run smoother?

@fraser As anthony said before, this code doesn’t really need to go in the backend and calling it asynchronously may even be slower. The loop might look something like this:

for (let i = 0; i < 48; i++) {
    $w('#measurement' + (i + 1) + 'Text').text = item[i].measurement;
    $w('#protein' + (i + 1) + 'Text').text = item[i].protein;
    //etc etc
}

I’m guesstimating your setup here, but if you want to go farther, using a repeater and some loop similar to this should be much more efficient than having 48 manual dropdowns.

@skmedia Cheers ,i would have thought keeping page code as light as possible would speed up the load times would it now? or is essentially the same as it has to also load back end as well?

My set up is as below i entered your code into the back end but i get a undefined return on each value

export function populateNutrientsfood1 (collectionName,valueField) {
wixData.query(collectionName)
.limit(1)
.eq(“foodType”, valueField)
.find()
.then((results) => {
let items = results.items;
let item = items[0];
for ( let i = 0; i < 48; i++) {
$w(‘#measurement’ + (i + 1) + ‘Text’).text = item[i].measurement;
$w(‘#protein’ + (i + 1) + ‘Text’).text = item[i].protein;
$w(‘#carbohydrate’ + (i + 1) + ‘Text’).text = item[i].carbohydrate;
$w(‘#fat’ + (i + 1) + ‘Text’).text = item[i].fat;
$w(‘#calories’ + (i + 1) + ‘Text’).text = item[i].calories;
}
console.log(results.items)
})
. catch ((err) => {
let errorMsg = err;
console.log(errorMsg);
})
}

Heres what i did have in the back end previously that worked but didnt allow me to use just one backend call due to text elements breaking the loop

export function populateNutrientsfood1 (collectionName,valueField) {
wixData.query(collectionName)
.limit(1)
.eq(“foodType”, valueField)
.find()
.then((results) => {
let items = results.items;
let item = items[0];
let measurement = item.measurement;
let protein = item.protein
let carbohydrates = item.carbs
let fat = item.fat;
let calories = item.calories;
for ( let i = 0; i < 48; i++) {
$w(‘#measurement’ + (i + 1) + ‘Text’).text = item[i].measurement;
$w(‘#protein’ + (i + 1) + ‘Text’).text = item[i].protein;
$w(‘#carbohydrate’ + (i + 1) + ‘Text’).text = item[i].carbohydrate;
$w(‘#fat’ + (i + 1) + ‘Text’).text = item[i].fat;
$w(‘#calories’ + (i + 1) + ‘Text’).text = item[i].calories;
}
console.log(results.items)
})
. catch ((err) => {
let errorMsg = err;
console.log(errorMsg);
})
}

@skmedia Cant get it to work its so close its annoying even more!!! lol

It removes undefined issues if i remove the (i) from the end of this item[i].measurement;

However it doesn’t loop correctly when i use it on drop down number 2 it doesnt populate text box 2 it seems to turn into an array and fill in all text boxes with same value from dropdown 1

@fraser Try putting this in your page’s frontend:

function populateNutrientsfood1 (collectionName,valueField) {     wixData.query(collectionName)         
.limit(200)         
.eq("foodType", valueField)         
.find()         
.then((results) => {  
    let item = results.items[0];  
    for (let i = 0; i < 48; i++) {         
        $w('#measurement' + (i + 1) + 'Text').text = item[i].measurement;         
        $w('#protein' + (i + 1) + 'Text').text = item[i].protein;         
        $w('#carbohydrate' + (i + 1) + 'Text').text = item[i].carbohydrate;         
        $w('#fat' + (i + 1) + 'Text').text = item[i].fat;         
        $w('#calories' + (i + 1) + 'Text').text = item[i].calories;         
    }
}
}

@skmedia it comes up with parsing errors.

ive never understood the duplicate scenarios can you describe what its trying to do ?

$w(‘#measurement#measurement’ + (i + 1) + ‘Text’).text = item[i].measurement;

also says $w should only have one argument

how do i clear the errors?

@fraser Hashtags in the Wix Forum app automatically duplicate…just delete the duplicates.

@skmedia lol that’s useful!!!

i still cant get it to work mate am i just using this in the front end and its not calling the back end?

my backend function is in the public folder its the same as backend right just as secure?

sorry to be a thick mate been looking at this too long i think

@fraser Lol no worries. Parsing errors are usually just syntax, so make sure all brackets are closed and you don’t have too many or don’t have syntax in the wrong place.

But in this case we’ve only defined the function, you’re never calling it. Place the function outside the page onReady, then call it inside the onReady using populateNutrientsFood();

@skmedia Ive cleared the code and believe all is in place yet nothing happens on the page and no errors

im confused


@fraser It should be $w(‘#foodDropdownList’).value

@skmedia yeah i thought that too but still nothing.

import wixData from ‘wix-data’;

$w.onReady( function () {
});

export function food1Dropdownlist_change(event) {
populateNutrientsfood ();
}

function populateNutrientsfood () {
wixData.query(“MyFoods”)
.limit(100)
.eq(“foodType”, $w(“#food1Dropdownlist”).value)
.find()
.then((results) => {
let item = results.items[0];
for ( let i = 0; i < 48; i++) {
$w(‘#measurement’ + (i + 1) + ‘Text’).text = item[i].measurement;
$w(‘#protein’ + (i + 1) + ‘Text’).text = item[i].protein;
$w(‘#carbohydrate’ + (i + 1) + ‘Text’).text = item[i].carbohydrate;
$w(‘#fat’ + (i + 1) + ‘Text’).text = item[i].fat;
$w(‘#calories’ + (i + 1) + ‘Text’).text = item[i].calories;
}
})
}

@fraser let item = results.items;

Otherwise you’re taking results.items[0][i], which makes no sense.