Code Check -- Function Return Promise

Any ideas why this basic code isn’t working?


projectQuery()
	.then((projItems) => {
	console.log(projItems);
	});
	
function projectQuery () {
	return "Test";
}

Hi David!
You should read about promises more - Promise - JavaScript | MDN

You can call “then” only on promise, not on regular function.
This is example that works:

let projQuery = new Promise((resolve) => {	
	resolve("Test"); 
});

projQuery.then((projItems) => {
	console.log(projItems);
	});

Hey David,

The problem with your basic code, is that it’s too basic.

It’s like this - if you check your page code, you will probably notice that the you get a warning:
‘then’ is undefined
There’s a good reason for that - .then is in fact undefined. You need to wrap your function in a Promise.

Providing a full tutorial of Promises is beyone the scope of this forum, but here’s a quick and abbreviated explanation:

Promises are used to handle asynchronous processes, although synchronous processes (like your code) can also be wrapped in a Promise although somewhat lacking in meaning.

Promises alllow you to initiate an action which may take time (waiting for a response from an online servce), while allowing your code to continue. This ensures that your user isn’t left wondering if your site died.

Here’s some code that sort of Promisifiys your code:

let promise = new Promise(function(resolve, reject) {
  resolve("test");
});

// resolve runs the first function in .then
promise.then(
  result => console.log(result), // shows "done!" after 1 second
  error => console.log(error)    // doesn't run
);

Let’s fake asynchronicity with a timeout:

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("test"), 1000); // wait 1000 milliseconds
});

// resolve runs the first function in .then
promise.then(
  result => console.log(result), // shows "done!" after 1 second
  error => console.log(error) // doesn't run
);

Since there is no possibility of failure here, we get the same result - but only after a 1 second delay.

If the resolve() routine would have been something with a possiblity of failure (e.g. loading an image from an online service), then after some time transpires:

  1. on success, resolve would invoke the first function, result

  2. on failure, reject would invoke the second function, error
    There is a tremendous amount of material on the Internet regarding Promises. Do a search and you will be inundated with results. I promise.

All the best,

Yisrael

Ok – Resources on Promises were super helpful, I’ve spent a decent chunk of time going down the rabbit hole researching this and several other things. Unfortunately, I may have tried to dumb down my question and code too much and missed a critical piece. I’ve pasted a slightly more detailed version of my code below.

Yisrael, Mikhail – Either of you see anything obvious that is preventing this code form working?

Essentially, I am running a for loop in order to populate a repeater. The part that makes this difficult is I need data from two different datasets, that are linked together by an attribute. Fortunately, the code works, just not in the order that I need it to. The problem is that the repeater populates itself with data before the function that pulls data from the second dataset has time to run. So, when I try to set the repeater data to the second dataset attribute, it thinks it is undefined.

Is there some way that I can get these to run parallel or in sync or something?

wixData.query("Project_Submission")
	.ne("OrgComplete", "Yes")
	.find()
	.then( (results) => {
	const projItems = results.items;			   			    
	const itemsCount = results.items.length;
		
	for (let i = 0; i < itemsCount; i++) {
		
	let promise = new Promise(function(resolve, reject) 
	{ resolve(getCauses(projItems[i].org_id)); 					
	
	promise.then(  result => 
	
//Create Repeater Data						
	repeaterData.push({
	"proj_id": "project" + (i + 1),
	"_id": projItems[i]._id
	"causes": result,
	});
	);				
	}

	// set the repeater data, triggering the creation of new items
$w("#repeater2").data = repeaterData;
console.log(repeaterData);
				});
						
function getCauses(org_id) {
	
		wixData.get("Organizations", org_id)
	  	.then( (results) => {
	    let org_results = results;
	    let parsed_causes = JSON.parse(org_results.causes);
	    var result = parsed_causes.map(a => a.causes);
	    console.log(result);
		return results;
		});

}

Hi!

First idea that comes to my mind is this -
$w(" #repeater2 ").data = repeaterData;
console.log(repeaterData);
it’s not inside promise. So, it starts executing befrore loop is finished (and fills in repeaterData variable)
Is this what you see?
And please, share a link so i can see the current result of your code