I've been trying ALL weekend to onboard a client that I should have onboarded by the end of last week!
Goal:
I would like to create a profile for the client so that I can get their 'dashboard' setup before they login for the first time. Setup is required because I have different Client Types and different Plan Options. What the user sees on their dashboard depends on which type of client they are and on the plan they've selected. To accomplish this, I use repeaters which are informed by the details I've inputted into a 'companyInformation' database.
My desired workflow is as follows:
Lead communicates their desire to become a Client >
I create their Profile, Approve Them In WIX CRM which generates an Automated Email directing them to the Client Agreement page >
Upon submission of Client Agreement form, they are directed to the Registration Page where they sign in using their email address and the password I created for them >
They can update their Profile, Assign Tasks, Purchase Hours, etc.
Problem:
An ID is created for the member, but the email address is NOT being captured when I register them. Here's what the database looks like after I've registered them:
![](https://static.wixstatic.com/media/a27d24_d702353fa41e4d4ca87551ba41137691~mv2.png/v1/fill/w_49,h_3,al_c,q_85,usm_0.66_1.00_0.01,blur_2,enc_auto/a27d24_d702353fa41e4d4ca87551ba41137691~mv2.png)
Here's what the registration page looks like:
![](https://static.wixstatic.com/media/a27d24_8d71823e269d4a45bce465e857c84fa4~mv2.png/v1/fill/w_65,h_51,al_c,q_85,usm_0.66_1.00_0.01,blur_2,enc_auto/a27d24_8d71823e269d4a45bce465e857c84fa4~mv2.png)
Can someone PLEASE review the page code I'm using to tell me what's going wrong?
import wixUsers from 'wix-users';
import wixData from 'wix-data';
import wixWindow from 'wix-window';
import wixLocation from 'wix-location';
$w.onReady(() => {
if (wixWindow.rendering.renderCycle === 1) {
if (wixUsers.currentUser.loggedIn) {
$w("#register").label = "Logout";
$w("#showdashboard").show();
} else {
$w("#register").label = "Login/Register";
$w("#showdashboard").hide();
wixLocation.to(`/Profile/My-Profile/${wixUsers.currentUser.id}`);
}
}
});
export function register_onclick(event) {
// user is logged in
if(wixUsers.currentUser.loggedIn) {
// log the user out
wixUsers.logout()
.then( () => {
// update buttons accordingly
$w("#register").label = "Login";
$w("#showdashboard").hide();
} );
}
// user is logged out
else {
let userId;
let userEmail;
// prompt the user to log in
wixUsers.promptLogin( {"mode": "login"} )
.then( (user) => {
userId = user.id;
return user.getEmail();
} )
.then( (email) => {
// check if there is an item for the user in the collection
userEmail = email;
return wixData.query("Profile")
.eq("_id", userId)
.find();
} )
.then( (results) => {
// if an item for the user is not found
if (results.items.length === 0) {
// create an item
const toInsert = {
"_id": userId,
"email": userEmail
};
// add the item to the collection
wixData.insert("Profile", toInsert)
.catch( (err) => {
console.log(err);
} );
}
// update buttons accordingly
$w("#register").label = "Logout";
$w("#showdashboard").show();
} )
.catch( (err) => {
console.log(err);
} );
}
}
export function showdashboard_onclick() {
wixLocation.to(`/Profile/My-Dashboard/${wixUsers.currentUser.id}`);
}
don't use the export for onclick method use the onclick inside the onready function and also use the onClick method like this
$w("#registerbutton").onclick( (event)=>{
//write your function inside this
});
Correct ! Well done.
This is SO helpful! Block 5 is left open in your example, right?? You're the best! I really can't thank you enough!
Hi Juanita:
Good to hear you sorted it out. I think you are based in the US, I'm in the UK so hard to respond to questions in real time except where our days overlap!
One thing that I will suggest is that you take a look at the training material on this site:
https://www.w3schools.com/html/default.asp
When you get to this page there is a menu of different web technologies across the top of the page
This is all free reference and tutorial material on most things you might need help with when using languages such as Javascript. Also stackoverflow.com can be a useful reference site. But make sure you don't ask questions that have already been answered, the community will let you know in no uncertain terms if you do that. But this is a great resource if you want to get an answer to many problems. Simply search for the error you are seeing and someone is likely to have asked about it and received an answer.
Now the use of curly braces is addressed here: https://www.w3schools.com/js/js_statements.asp
Basically you need to make sure that you always keep the braces matching because they define a code block.
i.e. { } are matched and define a block. { without } is an open block and confuses the javascript interpreter as I mentioned above.
So when we write code we generally use indentation to help us figure out that we have matching braces.
If it makes it easier, adding comments can also help you figure out where there is a problem.
Can you see the problem with the example below?
{ // Start Main block { // Start Block 1 { // Start Block 2 } // End Block 2 } // End Block 1 { // Start Block 3 { // Start Block 4 { // Start Block 5 } // End Block 4 } // End Block 3 } // End Main Block
As you get more experienced you will see how others write their code, or encounter coding standards that are designed to help others read your code and make the code easier to debug :-)
Hope this is helpful.
TWO MORE CURLY BRACKETS DID THE TRICK!
I'm beggggiiiinnnngggg!!!! I've read everything I can read on my own trying to figure out where my error is to no avail. Pleeeeeaassse help!!! I'm a java illiterate!!!
I'm trying to figure out how to close it!! I've moved the bracket to a couple different places, but I keep getting errors . . . please don't leave me now!!!
Like this?
Hi Juanita:
the problem is that the function - register_onclick(event) isn't closed.
By this i mean that you need to put a '}' character after the catch statement before the last exported function. The Wix Editor is probably flagging an error at this point also.
Basically the javascript interpreter thinks that the function showdashboard_onclick is inside theregister_onclick(event) function and so doesn't like seeing an export function embedded in another function :-)
Thank you, stcroppe!! You have the patience of Job!! I got an error on the line pictured below. It's currently the last line of code and the error says: "Parsing error: 'import' and 'export' may only appear at the top level"
Which line do you think I should move it up to?
export function showdashboard_onclick(event, $w) { wixLocation.to(`/Profile/My-Dashboard/${wixUsers.currentUser.id}`); }
Here's what the whole code looks like now:
import wixUsers from 'wix-users'; import wixData from 'wix-data'; import wixWindow from 'wix-window'; import wixLocation from 'wix-location'; $w.onReady(() => { if (wixWindow.rendering.renderCycle === 1) { if (wixUsers.currentUser.loggedIn) { $w("#register").label = "Logout"; $w("#showdashboard").show(); } else { $w("#register").label = "Login/Register"; $w("#showdashboard").hide(); } } }); export function register_onclick(event) { // user is logged in if (wixUsers.currentUser.loggedIn) { // log the user out wixUsers.logout() .then(() => { // update buttons accordingly $w("#register").label = "Login"; $w("#showdashboard").hide(); }); } // user is logged out else { let userId; let userEmail; // prompt the user to log in wixUsers.promptLogin({ "mode": "login" }) .then((user) => { userId = user.id; return user.getEmail(); }) .then((email) => { // check if there is an item for the user in the collection // PER JEROME'S SUGGESTION console.log('User Email Address is:'+email); userEmail = email; return wixData.query("Profile").eq("email", userEmail).find(); }) .then((results) => { // if an item for the user is not found // PER JEROME'S SUGGESTION console.log('Profile records returned for '+userEmail+' = '+results.items.length); if (results.items.length === 0) { // create an item const toInsert = { "_id": userId, "email": userEmail}; // add the item to the collection wixData.insert("Profile", toInsert) .catch((err) => { console.log(err); }); } else if (results.items.length > 1) { // You may want to do something else here console.log('Oh no we have too many ['+results.items.length+'] Profile records for '+userEmail); } else { // In production code when you have finished debugging the page // This else clause could be removed console.log('We have seen this user before and things are good!'); } // update buttons accordingly $w("#register").label = "Logout"; $w("#showdashboard").show(); }) .catch((err) => { console.log(err); }); export function showdashboard_onclick(event, $w) { wixLocation.to(`/Profile/My-Dashboard/${wixUsers.currentUser.id}`); }
Hi Juanita:
So a quick javascript tutorial and another mia copa.
When you use strings in javascript you can join them using the '+' character. This is useful because you can join strings together with information in const, var and let variables.
So
let i = 1; let j = 2; console.log('The calculation '+i+' + '+j+' = '+(i+j)); // Should print "The calculation 1 + 2 = 3"
Now the problem with the line of code I gave you is that it is missing a + . If you look at the screen dump you have shared the last section of red text is showing you where the error is
So
'Profile records returned for '+userEmail+' = 'results.items.length
should be
'Profile records returned for '+userEmail+' = '+results.items.length
This should help you out.
Cheers
@jereome: I don't know if this is helpful, but here's what the console log looks like after changing my code using the advice offered by stcroppe;
| ^
I can't even tell you how grateful I am for you guys' help!! I've updated my code with the example provided by stcroppe, but I got an error on the line that says:
console.log('Profile records returned for '+userEmail+' = 'results.items.length);
Here's how my code looks with those changes:
import wixUsers from 'wix-users'; import wixData from 'wix-data'; import wixWindow from 'wix-window'; import wixLocation from 'wix-location'; $w.onReady(() => { if (wixWindow.rendering.renderCycle === 1) { if (wixUsers.currentUser.loggedIn) { $w("#register").label = "Logout"; $w("#showdashboard").show(); } else { $w("#register").label = "Login/Register"; $w("#showdashboard").hide(); } } }); export function register_onclick(event) { // user is logged in if (wixUsers.currentUser.loggedIn) { // log the user out wixUsers.logout() .then(() => { // update buttons accordingly $w("#register").label = "Login"; $w("#showdashboard").hide(); }); } // user is logged out else { let userId; let userEmail; // prompt the user to log in wixUsers.promptLogin({ "mode": "login" }) .then((user) => { userId = user.id; return user.getEmail(); }) .then((email) => { // check if there is an item for the user in the collection // PER JEROME'S SUGGESTION console.log('User Email Address is:'+email); userEmail = email; return wixData.query("Profile").eq("email", userEmail).find(); }) .then((results) => { // if an item for the user is not found // PER JEROME'S SUGGESTION console.log('Profile records returned for '+userEmail+' = 'results.items.length); if (results.items.length === 0) { // create an item const toInsert = { "_id": userId, "email": userEmail}; // add the item to the collection wixData.insert("Profile", toInsert) .catch((err) => { console.log(err); }); } else if (results.items.length > 1) { // You may want to do something else here console.log('Oh no we have too many ['+results.items.length+'] Profile records for '+userEmail); } else { // In production code when you have finished debugging the page // This else clause could be removed console.log('We have seen this user before and things are good!'); } // update buttons accordingly $w("#register").label = "Logout"; $w("#showdashboard").show(); }) .catch((err) => { console.log(err); }); export function showdashboard_onclick() { wixLocation.to(`/Profile/My-Dashboard/${wixUsers.currentUser.id}`);
Juanita:
Sorry I forgot you are a newbie to javascripting.
This line
.eq("email", userEmail) < -- -- -- -- -- -- - ensure unique use of email
Doesn't work because it was me highlighting the changed test in your .eq(). If you remove everything to the right of the closing parenthesis (i.e. < -- -- -- -- -- -- - ensure unique use of email ) it should be fine
So the code should be:
.eq("email", userEmail)
The other thing I would do is handle the case where this test fails:
if (results.items.length === 0)
So you actually want to do something (at least for testing purposes if nothing else) on two other conditions. One condition is
} else if (results.items.length > 1) {
In this case you have detected duplicate records with the same email address which is something you don't want to happen and should have a consequence right?
the other condition is:
} else { // Essentially this verifies a matching record
SO your code would look something like (note: something like not necessarily exactly like ;-)) this
// prompt the user to log in wixUsers.promptLogin({ "mode": "login" }) .then((user) => { userId = user.id; return user.getEmail(); }) .then((email) => { // check if there is an item for the user in the collection // PER JEROME'S SUGGESTION console.log('User Email Address is:'+email); userEmail = email; return wixData.query("Profile").eq("email", userEmail).find(); }) .then((results) => { // if an item for the user is not found // PER JEROME'S SUGGESTION console.log('Profile records returned for '+userEmail+' = 'results.items.length); if (results.items.length === 0) { // create an item const toInsert = { "_id": userId, "email": userEmail}; // add the item to the collection wixData.insert("Profile", toInsert) .catch((err) => { console.log(err); }); } else if (results.items.length > 1) { // You may want to do something else here console.log('Oh no we have too many ['+results.items.length+'] Profile records for '+userEmail); } else { // In production code when you have finished debugging the page // This else clause could be removed console.log('We have seen this user before and things are good!'); } // update buttons accordingly $w("#register").label = "Logout"; $w("#showdashboard").show(); }) .catch((err) => { console.log(err); });
Hi Juanita
I went through the same process a few moths back trying to create users first and encountered the same problems as you are doing now.. The problem is, as you know by now, that the WiX login module creates a unique id and assigns that to an email address the moment a new contact is created in WiX Contacts, therefor if an account has been creaetd before a member signs up for the first time, there will be a duplicate entry.
So my advice will be to turn the auto-aprove back on, create profiles for clients by actually signing them up throught he WiX login module and then populate their accounts in the database after the login module has created the profile in the database.. True, you will have to find another solution for when they actually login for the first time what the email is concerned, but that shouldn't be too difficult as you could build a 'logged in' counter to the database and when it is equals to 1, send a triggered email.
I hope this helps!
Tiaan
Regarding console : it allows you to debug your code by printing messages, available in preview and browser's consoles, just like you showed.
So in your case we want to know why a record is created with empty email. So I would add the following lines:
.then((email) => { // check if there is an item for the user in the collection console.log("Email retrieved : " + email); userEmail = email;
and
const toInsert = { "_id": userId, "email": userEmail }; console.log("toInsert :" + toInsert);
Execute in preview mode and tell us the result.
@stcroppe - YOU are obviously WAYYYYYY smarter than me! I am certain that all of this would make perfect sense to someone closer to your speed, but you just left me in the dust, lol! Thanks sooooo much for your help though. I'm trying my best to make heads or tails of it. I'm almost positive that I am in total agreement with this part of your post: "If you need your membership records to be unique based on email address [I would :-)] so your email address is a unique data collection key which you should (as you have already ascertained) check for not the _id. So your code needs to be as follows. This will prevent multiple records being added with the same key email address. " So I made the following change:
// prompt the user to log in wixUsers.promptLogin({ "mode": "login" }) .then((user) => { userId = user.id; return user.getEmail(); }) .then((email) => { // check if there is an item for the user in the collection userEmail = email; return wixData.query("Profile") .eq("email", userEmail) < -- -- -- -- -- -- - ensure unique use of email .find(); }) .then((results) => { // if an item for the user is not found if (results.items.length === 0) { // create an item const toInsert = { "_id": userId, "email": userEmail }; // add the item to the collection wixData.insert("Profile", toInsert) .catch((err) => { console.log(err); }); } // update buttons accordingly $w("#register").label = "Logout"; $w("#showdashboard").show(); }) .catch((err) => { console.log(err); }); } }
Unfortunately, I got an error on this line:
.eq("email", userEmail) < -- -- -- -- -- -- - ensure unique use of email
This is the part of your post where things get super confusing for me: "Now the other problem that exists with the wix CRM is that it allows multiple records with the same email address. If you use wix-crm to create a contact and wix-users to register and log in then you will get two records with the same email . . . " I definitely need my user's email addresses to be unique.
If you record the id created by wix-crm.createContact it will not be the same one generated by wix-users.register(). The id you need to record for log in purposes is the one from the register() function.
How would I go about achieving this?
Now the only way to send a triggered email when the user is NOT logged in is using the wix-crm.emailContact function not wix-users.emailUser. What this means is that you also need the id from wix-crm.createContact so you need to track both id's in your user "Profile" data collection and use the correct one for the specific purpose you have in mind. "
How would I go about achieving this?
I've read countless posts (including the one you referred to in your post) trying to see if I could figure this out on my own, but unfortunately, I'm not advanced enough fill in the holes.
I am SO grateful for any additional help you're willing to provide with this!!!
Hi Juanita:
Something to consider is that your query to test for a previously created record does this:
return wixData.query("Profile") .eq("_id", userId) .find(); } ) .then( (results) => { // if an item for the user is not found if (results.items.length === 0) {
If you need your membership records to be unique based on email address [I would :-)] so your email address is a unique data collection key which you should (as you have already ascertained) check for not the _id. So your code needs to be as follows. This will prevent multiple records being added with the same key email address.
return wixData.query("Profile") .eq("email", userEmail) <------------- ensure unique use of email .find(); } ) .then( (results) => { // if an item for the user is not found if (results.items.length === 0) {
Now the other problem that exists with the wix CRM is that it allows multiple records with the same email address. If you use wix-crm to create a contact and wix-users to register and log in then you will get two records with the same email. If you record the id created by wix-crm.createContact it will not be the same one generated by wix-users.register(). The id you need to record for log in purposes is the one from the register() function. Now the only way to send a triggered email when the user is NOT logged in is using the wix-crm.emailContact function not wix-users.emailUser. What this means is that you also need the id from wix-crm.createContact so you need to track both id's in your user "Profile" data collection and use the correct one for the specific purpose you have in mind.
I hope this makes sense.
Take a look at this thread that dealt with a similar issue.
https://www.wix.com/code/home/forum/community-discussion/triggered-email-template-replace-variables-in-links
@Tiaan - My original plan was to manually create my clients in the database so I could send them a "Next Steps" email and attempt to control the password they used so that I could log in to their account from time to time to ensure the dynamic pages were functioning properly. The problem I encountered doing things that way is that, in short, it doesn't work. Despite there being an existing email address on the database, the system created a new member. Therefore, I was forced to turn the auto-approve off and set up a triggered "Next Steps" email that would be sent to the client after they were "approved" as a member. Do you think the source of the problem is that my site is not currently set to auto-approve members?
@jeromechauveau: is this what I'm supposed to read? If yes, I REALLY need help because I have no clue what any of it means. Pleeeeaaassseee help!