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 IDiscreated 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:
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}`);
}
Your code looks good… I’m taking a stab in the dark here, but I’ve experienced a similar problem where auto-approval for new members is turned off, I’d suggest check that first.
If the ID is created in the db then I doubt there’s a problem with your database permissions, but just in case, change permissions to ‘anyone’ right through and see if that works. If it does then you can tighten it up one by one form there…
@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?
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.
@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!!!
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;
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.
.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);
});
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}`);
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
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}`);
}
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
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!!!
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!!!