[SOLVED] Trigger error message when promise rejected

This is a simplified edit from my original post that is still giving me fits, and I’m hoping for a solution! crosses fingers

I have a _beforeInsert hook that contains a promise that runs on the backend data.js file that searches for dups in the db. It works. However, after banging my head on my screen, wall, and desk for days, I am still not getting how to have text (#errorMessage) triggered when promise is rejected.

I have tried adding $w('#errorMessage) under my reject(); code, but it alerts me that it isn’t a valid selector. This seems like it should be easy, but apparently it’s beyond my comprehension.

My data.js code:

import wixData from ‘wix-data’;

export function FitnessSignup_beforeInsert(item, context) {
console.log(“in before insert hook”);
console.log("user is " + item.combine);
let p = new Promise( function (resolve, reject)
{
console.log(“in promise body”);
let user_q = wixData.query(“FitnessSignup”).eq(“combine”, item.combine);
user_q.count().then(count =>
{
console.log(“after big_q returns”);
if (count === 0) {
console.log(“count is zero, no dups found, resolving the promise to the original ‘item’ so the insert can proceed”);
resolve(item);
}
else {
console.log(“count is more than zero, rejecting the promise with an error message”);
reject(“count is more than 0, dups found!”);
}
})
});
return p;
}

Poke :slight_smile:

Alright, getting somewhere maybe?

I’ve added a dataset error function to my page code to show #errorText, however, it now shows whenever there is ANY error - for instance, with validation, too. So now I have the validation error popping up AND my specific “you’ve already signed up” error text popping up.

I did attempt to separate the two and specify that only #errorText show() when the error message equals specific text, but it alerts me that error (.message) isn’t defined:

export function fitnessSignups_error () {
if (error.message === ‘count is more than 0, dups found!’)
$w(‘#errorText’).show();
$w(‘#box1’).hide(‘float’, floatOptions);
$w(‘#switch1’).disable();
}

Hi Brett:

There are two ways to deal with this. You can use the promise mechanism or you can use the .then .catch pattern.

In your page code when you call the insert() function you can do either

wixData.insert('<data collection name>', <item object>)
// Then bgehaves like a Promise so takes resolve and reject 
// function arguments 
.then(insertResolved, insertRejected);

// Define the resolve and reject functionjs
function insertResolved(insertedObject) {
   // Do something with inserted Object
}

function insertReject(error) {
     $w('#errorMessage').value = error.message;
}

or you can use the then catch pattern

wixData.insert('<data collection name>', <item object>)
// Use the same functions as above
.then(insertResolved)
.catch(insertRejected);

Of course you don’t need to use functions you can use anonymous pointer functions but this might be more difficult to read:

wixData.insert('<data collection name>', <item object>) 
// use anonymous resolve function 
.then((insertedObject) => {
    // Process inserted Object
 },
 // use optional anonymous reject function
 (error) => {
     $w('#errorMessage').value = error.message;
 });

Also read the MDN Promise documentation to get a better idea of how to use Promises. The .then() documentation should help you out.

Hope this helps!

Hey Stcroppe!

I sincerely appreciate your help! I took your suggestions and messed around with them all day yesterday since you posted. Tried different variations and read the suggested materials (GREAT info, btw!). I do find myself just seconds away from blowing this whole thing up out of frustration, though! haha

The code looks and reads like it should be operating the intended way, but it isn’t. And all because of one minor issue that I can’t seem to resolve. I will try to keep this brief and explain what and why it’s important:

The company that I’m attempting this site for REQUIRES all participants to agree to their waiver and release of liability. I have set this agreeance up with a switch that the user toggles, default to no, and switched to yes. If yes value present, it expands a box that contains an input for their email, then submit button. If switch toggled back to no value, it hides the box, making it so the switch HAS to have a yes value to submit/join.

I have been able to code that the switch disables on a successful submission, and would very much like to preform the same task for when the code reports back as a duplicate - and THAT is what is not working. In a nutshell, everything works: input drops on switch, input correctly validates email, input hides when switch equals ‘no’, and my hook even correctly finds and reports back any dups with my error text (Thank you!). But that’s where the fun stops as the switch is still shown in the ‘yes’ toggle position. This is problematic because, for some reason, when this happens and the user then switches to ‘no’, it reveals the email input and would technically allow them to signup (with an unused email) while NOT agreeing to the terms. I know that if I can just find a way to disable the switch when a dup is found, it would solve all issues.

I sincerely apologize for the long text, but would honestly rather provide too much information than not enough. And, with that said, I will provide all my code for the page and backend js:

Backend/data.js:

import wixData from ‘wix-data’;

export function FitnessSignup_beforeInsert(item, context) {
console.log(“in before insert hook”);
console.log("user is " + item.combine);
let p = new Promise( function (resolve, reject)
{
console.log(“in promise body”);
let user_q = wixData.query(“FitnessSignup”).eq(“combine”, item.combine);
user_q.count().then(count =>
{
console.log(“after big_q returns”);
if (count === 0) {
console.log(“count is zero, no dups found, resolving the promise to the original ‘item’ so the insert can proceed”);
resolve(item);
}
else {
console.log(“count is more than zero, rejecting the promise with an error message”);
reject(“count is more than 0, dups found!”);
}
})
});
return p;
}

Page code:

import wixLocation from ‘wix-location’;
import wixData from ‘wix-data’;

$w.onReady( function () {
$w(“#fitnessSignups”).onBeforeSave( function () {
$w(“#fitnessSignups”).setFieldValue(‘site’, $w(‘#text10’).text);
$w(“#fitnessSignups”).setFieldValue(‘exercise’, $w(‘#text2’).text);
$w(“#fitnessSignups”).setFieldValue(‘day’, $w(‘#text3’).text);
$w(“#fitnessSignups”).setFieldValue(‘time’, $w(‘#text4’).text);
$w(“#fitnessSignups”).setFieldValue(‘location’, $w(‘#text8’).text);
$w(“#fitnessSignups”).setFieldValue(‘classId’, $w(‘#text15’).text);
$w(“#fitnessSignups”).setFieldValue(‘combine’, $w(‘#text15’).text + $w(“#input1”).value);
$w(“#fitnessSignups”).setFieldValue(‘remove’, ‘Leave class’);
});

$w('#fitnessSignups').onAfterSave(()=>{ 
    setTimeout( **function** (){ 

if ($w(‘#success’).isVisible) {
$w(‘#box1’).hide(‘float’, floatOptions);
$w(‘#switch1’).disable();
}
});
});

$w("#dropdown1").onChange((event, $w) => { 
    console.log(event.target.value); 
    wixLocation.to(event.target.value); 
}); 

});

let floatOptions = {
“duration”: 500,
“delay”: 0,
“direction”: “top”
};

export function switch1_click (event, $w) {
if ($w(‘#box1’).isVisible) {
$w(‘#box1’).hide(‘float’, floatOptions);
$w(‘#errorText’).hide(‘float’, floatOptions);
}

else {
$w(‘#box1’).show();
}
}

export function button2_click(event, $w) {
wixData.query(“FitnessSignup”)
.eq(‘combine’, $w(‘#text15’).text + $w(“#input1”).value)
.find()
.then((results) => {
if (results.length > 0) {
//id is not unique. show error and disable submit button
$w(‘#box1’).hide(‘float’, floatOptions);
$w(‘#errorText’).show();
$w(‘#switch1’).disable();
}
else {
//id is unique. do nothing
}
}). catch ((err) => {
let errorMsg = err;
});
}

I do appreciate your time with this!

Hi brett:

Ok well without seeing the page you are having problems with its a little tough to give you accurate feedback.

Things to consider include:

  1. Duplication of code. It seems to me that the wixData.query() in the button2_click event handler is repeating ( or closely repeating ) the query in the FitnessSignup_beforeInsert() handler. The difference being that one is testing item.combine the other is testing the join of two text fields?

  2. I am assuming that you have connected a dataset to the page called #fitnessSignups and you have bound its submit action to button2. So it seems to me that you will kick off two essentially parallel queries that may or may not complete in the order you are expecting. But because you are not in control of the submit you don’t know :-). If you are dependent upon the outcome of the submit then I would remove the dataset binding from the element and execute the dataset .save() function from the button2 handler. This way you can hook a .then() to the save (which returns a promise) and then perform your error handling or check box clean up.

  3. You are using isVisible to determine your #box1 toggle switch setting in an onClick event handler. Two thoughts here.
    a) I would recommend testing $w(‘#box1’).hidden instead of using isVisible. If you happen to scroll the toggle switch off of the visible window then that also counts as not visible. So if the #switch1 event fires while the #box1 is not hidden (showing) BUT is not on screen then the isVisible test will fail :slight_smile:
    b) I would test which event handler is best for the element you are working with too. If #switch1 is a switch and it is dragged will the onClick event fire? Would you be better off using an onChange handler since you want to do something when the toggle switch value changes?

Hope this inspires some additional avenues of research for you :wink:

Steve

Steve,

I am in the process of running through your suggestions! However, I did want to provide you with a link to the section that is including this toggle switch, input, and button, so you can get the full effect of what I am attempting to explain! :slight_smile:

https://kernhigh.wixsite.com/empower/FitnessClasses/Centennial-High-School/Circuit-Training

Thank you! (Inspired indeed)

Brett

Updates:

Took your advice with the onClick hidden suggestion but still got the same result for when the error text showed. However, your suggestion gave me the idea to set the first if statement to look for if the error is visible, then setting the else/if to show box1. It seems perhaps a bit unorthodox, but it does retrieve the result I’m looking for!

Also have removed the query AND the dataset binding from the submit button (button2), and inputted the dataset save function. I do get the excepted result of success message and disabling of switch, and checked the db and does show that it has saved the entry. Also, the hook still successfully performs the dups check.

I still get the correct error text to show when dup is found, but can’t get that damn button to disable.

But still trudging on :slight_smile:

I have added console.log events to help trace this sucker. Upon more researching, I have taken my code in a bit of a different direction, mostly with placement. I have added a query beforeSave to control my error message with an if statement, and it works except for the disabling. So, I put it in an additional if statement alone to no avail.

When looking at the console logs, it shows the it’s been ‘disabled’, but it hasn’t.

Steve,

You can take the rest of the day off, I figured it out!!! Man, I need a drink after that one!

Thanks for your help and direction, it’s greatly appreciated here. :slight_smile:

Brett

Hi Brett

No problem.

Glad I helped get you to a place you needed to be!

Steve