Async/await issue between F/E & B/E - Help needed

Hi everybody,

I am - time and again - facing the following issue:

On page ready, I want to fill the options of a series of dropdown element on my page. For this, I have a combination of F/E and B/E (for all collection queries) functions that, while in developer mode, work appropriately, but on the live site the relevant arrays generated in the B/E are not recognized (console message: “arr is undefined”):

To better understand the code, here are the basic logical steps, if needed:

Step 0) call back end function from the front end (steps 1) to 4) ), “on ready”, by indicating the chosen language of the page, then (step 5) ) allocate arrays to dropdown elements identified by “keys” in dropdown collection
Step 1) in the back end, get a list of dropdown elements (per “#…” key) to be populated (“DropdownElements” collection only holds a list of “$w(”#…“)” references to be run through,
Step 2) per dropdown element, get those items for which there is currently an event and get _ids from a “source collection”,
Step 3) get the corresponding values from a reference collection containing the list of labels corresponding to the _ids, depending on the language chosen
Step 4) deliver array of eligible dropdown label/value pairs to front end and fill the corresponding dropdown options

Can somebody please help with this? It is pretty urgent, as this is a service to Ukrainian refugees in our area …

THANK YOU SO MUCH FOR YOUR SUPPORT!

There is a unfinished desktop version live (www.lachen-hilft.ch), where the missing dropdown options become visible (and as a result, some other functions do not work)

Here is a (a bit shortened version of) the code:

// F/E: call function "load content" on ready, calling up, a.o. the "initialDropDowns (language)" F/E function
$w.onReady(function () {
	let language = $w('#language').text
	loadContent(language)
});

// load initial page content, a.o., call function to load dropdown options
export function loadContent(language) {		
	staticElements(language)
	loadNavigation(language)
	initialDropDowns(language)
	initialPlaceholders(language)
	isLoaded();
	loadLesenswertes(language, pageInitial)
		$w('#lesenswertesPageCur').text = pageInitial.toString(	)
		$w('#lesenswertesPagePrev').disable()
	events(language, pageInitial, tlnInitial, katInitial, gemInitial)
		$w('#eventsPageCur').text = pageInitial.toString(	)
		$w('#eventsPagePrev').disable()	
	collapseAll();
	$w("#anchorIntro").scrollTo()
}

// F/E function calling the relevant B/E loadDropDowns(language) function
async function initialDropDowns(language) {	
	const arr = await loadDropDowns(language);
	loadDropDowns(language).then((response) => {
		const arr = response
		if(arr != undefined){
			if (arr.length > 0) {
				for (let i = 0; i < arr.length; i++) {
					let items = []
					let target = arr[i][0].key
					for (let j = 1; j < arr[i].length; j++) {
						const elementLabel = arr[i][j].label;
						const elementValue = arr[i][j].value;
						items.push({label: elementLabel, value: elementValue})
					}
					$w(target).options = items
					$w(target).value = undefined
					$w(target).placeholder = arr[i][1].label
				}
			}
		}
	});
}

//B/E function to query relevant collections

export async function loadDropDowns(language){

// step 1)
    let db = "DropdownElements"
    try{
        const data = await wixData.query(db)
            .eq("enabledDefault", true)
            .find()
        const result = await data.items

// step 2)    
    if (result.length > 0) {
            let arr = []
            for (let i = 0; i < result.length; i++) {
                let sourceCollection = result[i].sourceCollection.toString()
                let sourceField = result[i].sourceField.toString()
                let referenceCollection = result[i].referenceCollection.toString()
                let referenceField = (language + result[i].referenceField.toString())
                const results = await wixData.query(sourceCollection)
                    .include(sourceField)
                    .distinct(sourceField)        
                    const output = await results.items

// step 3)   
					if (output.length > 0) {

                        if (referenceCollection === "Gemeinden"){
                            const response = await wixData.query(referenceCollection)
                            .hasSome("_id", output)
                            .ascending(referenceField)
                            .find()
                                const keys = await response.items
    
								if (keys.length > 0) {
                                    arr[i] = []
                                    arr[i].push({"key": result[i].key})                                    

									// differentiate by language, push first "all" option into the array, then the relevant value/label pairs

                                    if (language === "") {
                                        if (result[i].selectedIndexDefault != 1){
                                            arr[i].push({
                                                "value": undefined,
                                                "label": result[i].text
                                        })
                                        }
                                        for (let j = 0; j < keys.length; j++) {
                                            arr[i].push({
                                            "value": keys[j]._id,
                                            "label": keys[j].gemeinde
                                            })
                                        }
                                    }
                                    else if (language === "u_") {
                                        if (result[i].selectedIndexDefault != 1){
                                        arr[i].push({
                                                "value": undefined,
                                                "label": result[i].u_text
                                            })
                                        }
                                        for (let j = 0; j < keys.length; j++) {
                                            arr[i].push({
                                            "value": keys[j]._id,
                                            "label": keys[j].u_gemeinde
                                            })
                                        }
                                    }
                                    else if (language === "r_") {
                                        if (result[i].selectedIndexDefault != 1){
                                        arr[i].push({
                                                "value": undefined,
                                                "label": result[i].r_text
                                            })
                                        }
                                        for (let j = 0; j < keys.length; j++) {
                                            arr[i].push({
                                            "value": keys[j]._id,
                                            "label": keys[j].r_gemeinde
                                            })
                                        }
                                    }
                                }
                            }

// alternatives to above reference collection "Gemeinde", depending on reference collection type (same code as above, just different field names)
//                        else if (...){...}                                   
//                        else if (...){...}
                    }                     
                }
            return arr
            }
        }
		catch(error) {console.log(error)
    }
}

Since this works in Preview, the issue could very well be database permissions.

You might just need to add the suppressAuth option. Your (backend) code should be something like this:

let options = {
 "suppressAuth": true,
};
const data = await wixData.query(db)
            .eq("enabledDefault", true)
            .find(options)
const result = data.items; // await not needed here

Note that in the initialDropDowns() FE function, you are incorrectly calling the BE function loadDropDowns() twice. This is your code:

    const arr = await loadDropDowns(language);
    loadDropDowns(language).then((response) => {
    ...

You should delete the first call (as the results are never used), and just use:

    loadDropDowns(language).then((response) => {

@yisrael-wix

Hi Yisrael,

good to see that you are still around, helping people out of their problems! As two years ago, always an honor!

Re your remarks:

  1. suppressAuth - have adjusted that in all B/E functions. And reset all collections to “site content” for the moment being …
  2. double call of loadDropDowns - adjusted that (was a systematic error)

But … still same issue. In live version “not defined”. In developer mode “preview” - no issue. Although the dropdowns load slowly …

Could it be … I am chaining a series of queries, to get the options for the dropdowns, in the B/E . Timeout issues possible? Could you please have another look at the chained queries hereafter?

I am pasting the (partially collapsed) code as a pic (if this is quicker to find for you …), and the code snippet of the entire B/E procedure, which does not return anything.


Here is the code:

export async function loadDropDowns(language){
    let db = "DropdownElements"
    try{
        const data = await wixData.query(db)
            .eq("enabledDefault", true)
            .find({
                "suppressAuth": true,
                "suppressHooks": true
            })
        const result = data.items
        if(result.length > 0) {
            let arr = []
            for (let i = 0; i < result.length; i++) {
                let sourceCollection = result[i].sourceCollection.toString()
                let sourceField = result[i].sourceField.toString()
                let referenceCollection = result[i].referenceCollection.toString()
                let referenceField = (language + result[i].referenceField.toString())
                const results = await wixData.query(sourceCollection)
                    .include(sourceField)
                    .distinct(sourceField)        
                    const output = results.items
                    if (output.length > 0) {
                        if (referenceCollection === "Gemeinden"){
                            const response = await wixData.query(referenceCollection)
                            .hasSome("_id", output)
                            .ascending(referenceField)
                            .find({
                                "suppressAuth": true,
                                "suppressHooks": true
                            })
                            const keys = response.items
                            if (keys.length > 0) {
                                arr[i] = []
                                arr[i].push({"key": result[i].key})                                    
                                if (language === "") {
                                    if (result[i].selectedIndexDefault != 1){
                                        arr[i].push({
                                            "value": undefined,
                                            "label": result[i].text
                                    })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].gemeinde
                                        })
                                    }
                                }
                                else if (language === "u_") {
                                    if (result[i].selectedIndexDefault != 1){
                                    arr[i].push({
                                            "value": undefined,
                                            "label": result[i].u_text
                                        })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].u_gemeinde
                                        })
                                    }
                                }
                                else if (language === "r_") {
                                    if (result[i].selectedIndexDefault != 1){
                                    arr[i].push({
                                            "value": undefined,
                                            "label": result[i].r_text
                                        })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].r_gemeinde
                                        })
                                    }
                                }
                            }
                        }
                        else if (referenceCollection === "Veranstalter"){
                            const response = await wixData.query(referenceCollection)
                            .hasSome("_id", output)
                            .ascending(referenceField)
                            .find({
                                "suppressAuth": true,
                                "suppressHooks": true
                            })
                            const keys = response.items
                            if (keys.length > 0) {
                                arr[i] = []
                                arr[i].push({"key": result[i].key})        
                                if (language === "") {
                                    if (result[i].selectedIndexDefault != 1){
                                    arr[i].push({
                                            "value": undefined,
                                            "label": result[i].text
                                        })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].veranstalter
                                        })
                                    }
                                }
                                else if (language === "u_") {
                                    if (result[i].selectedIndexDefault != 1){
                                    arr[i].push({
                                            "value": undefined,
                                            "label": result[i].u_text
                                        })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].u_veranstalter
                                        })
                                    }
                                }
                                else if (language === "r_") {
                                    if (result[i].selectedIndexDefault != 1){
                                    arr[i].push({
                                            "value": undefined,
                                            "label": result[i].r_text
                                        })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].r_veranstalter
                                        })
                                    }
                                }
                            }
                        }                                   
                        else if (referenceCollection != "Veranstalter" &&  referenceCollection != "Gemeinden" ) {
                            const response = await wixData.query(referenceCollection)
                            .hasSome("_id", output)
                            .ascending(referenceField)
                            .find({
                                "suppressAuth": true,
                                "suppressHooks": true
                            })
                            const keys = response.items
                            if (keys.length > 0) {
                                arr[i] = []
                                arr[i].push({"key": result[i].key})        
                                if (language === "") {
                                    if (result[i].selectedIndexDefault != 1){
                                    arr[i].push({
                                            "value": undefined,
                                            "label": result[i].text
                                        })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].kategorie
                                        })
                                    }
                                }
                                else if (language === "u_") {
                                    if (result[i].selectedIndexDefault != 1){
                                    arr[i].push({
                                            "value": undefined,
                                            "label": result[i].u_text
                                        })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].u_kategorie
                                        })
                                    }
                                }
                                else if (language === "r_") {
                                    if (result[i].selectedIndexDefault != 1){
                                    arr[i].push({
                                            "value": undefined,
                                            "label": result[i].r_text
                                        })
                                    }
                                    for (let j = 0; j < keys.length; j++) {
                                        arr[i].push({
                                        "value": keys[j]._id,
                                        "label": keys[j].r_kategorie
                                        })
                                    }
                                }
                            }
                        }
                    }                     
                }
            console.log("B/E dropdown arr", arr)
            return arr
            }
        }
    catch(error) {
        console.log(error)
    }
}

Thanks in advance!!
Thomas

Please realize that your code is not simple and is quite long. I looked at the code, and it’s not evident to me why it would work in Preview and not in Live. I suggest generously adding console.log() statements to your backend code so that you can see what’s happening along the way. Hopefully, in this way you can spot where it’s crapping out.

I do notice that you are performing queries inside of a loop, and that definitely raises the red flag of “time out” being the problem.

To be honest, it’s not clear to me what exactly you are trying to accomplish, but I do see that you have a reference field. Perhaps you can solve your problem using queryReferenced() instead of a plain query() .

The other approach would be to build each dropdown option list separately so that you won’t time out trying to build all of the dropdown at once. If you prefer to build all of the dropdowns in one place for convenience and code readability, you can create a function where you can build each dropdown, one at a time, but in the same calling function.

@yisrael-wix thanks, Yisrael! Yes, the code is not that simple. I will try the approaches you mentioned! Will try first with a generic function, pass the keys to be queried one by one, and then gather the result in a final array. It’s too complex the way it is built up to now.

The basic idea was to have the dropdowns (and some other elements) loaded upfront, before a user interacting with the site. But well, I might have overshot.

oh, and re the console.log statements - did that, step by step, checked the output in preview mode. No issue. It’s only in the live version where the array is not returned.

You’ll need to inspect the console output on the Live site. You can use the browser console , Live site events , or Google Operations .

@info56409 You’ll also find that a simpler approach is easier to implement, and much easier to maintain and change.

@yisrael-wix did that, too. That’s where the issue came up, once I published the site. Tried in different browser types - all the same. Result there: “undefined”
.

Wait a second … wrong pic

@yisrael-wix - here you go

@yisrael-wix the challenge of this is that you need to be great master to make difficult things look simple :-). Otherwise - yes, fully agree.

The issue is not linked to the B/E dropdown function. Tried a case with a single item - same result.

@yisrael-wix There is a warning message re Google Maps (just a quick check - if there is a possible issue, I will open a different post):

“DevTools failed to load source map: Could not load content for https://static.parastorage.com/services/editor-elements/dist/google-map.js.map: HTTP error: status code 403, net::ERR_HTTP_RESPONSE_CODE_FAILURE”

I have a few maps integrated in the site.

@yisrael-wix - SOLVED. Sorry for keeping you busy with my trials & tribulations. There was ONE collection (“Emergency Calls”) that for some reason was sent to “write only for members” … sucks. Now it works. Thanks for you support anyway!

Glad you got it worked out. You’re buying the beers. :beers:

@yisrael-wix I will :slight_smile: - virtually, as many as your screen resolution can cope with, unless you tell me, where you are located and I will offer you a couple of them, next time I’ll come over :slight_smile:

BUT … now that I have got your (still sober) attention :slight_smile: - I got an “options” problem in the following code, where I pass the “authority” options only at “find” (last line in the below snippet (the rest of the code afterwards is pure “data allocation”).

Again, access right issues in live, but using the same collections as the previous issue, which is now solved … so … do I have to suppress authority restrictions still somewhere else?

    let myQuery = await wixData.query(db)
        if(tln === "" && kat === "" && gem === "" ) {
            myQuery = await myQuery  
            .include("veranstalter")
            .gt("end", now)
            .ascending("end")
            .ascending("veranstalter")
            .ascending("titel")
        }
        if (tln != "" && kat === "" && gem === "") {
            myQuery = await myQuery
            .include("veranstalter")
            .eq("teilnehmer", tln)
            .gt("end", now)
            .ascending("end")
            .ascending("veranstalter")
            .ascending("titel")
        }
        return myQuery.find(options)
            .then((result) => {
            
            
            ETC....



SOLVED, too. Was an issue of a collection that previously held encrypted (personal information) fields, that apparently overwrote the general permission settings (site content) of the collection, as well as the “suppress authorities” options. After removing the encrypted fields and placing them in a separate collection, no more issues.

@yisrael-wix - you could (if there isn’t yet - I could not find it, at least) maybe recommend to your WIX development team to at least document the hierarchy of permission settings of a collection, i.e., that the existence of encrypted fields in any collection restricts any use of the fields in that collection to members with the required rights, independently of generic collection settings and suppress authority options used in a function to access that information. GDPR rules …