I’m trying to detect whether a user is returning or whether its is first time he visits the page:
var query = wixLocation.query;
if ( query.hasOwnProperty("mc_cid") && query.hasOwnProperty("mc_eid") && query.hasOwnProperty("utm_campaign") && query.hasOwnProperty("utm_medium") && query.hasOwnProperty("utm_source") && query.hasOwnProperty("utm_term") ) {
if ( query.mc_cid === "d2b577fa21" && query.mc_eid === "19aea8a42a" && query.utm_campaign ===
"WELCOME" && query.utm_medium === "email" && query.utm_source === "Individual" && query.utm_term === "0_2447fe98f0-d2b577fa21-407633493" ) {
console.log("accesspoint: e-mail");
if (query.hasOwnProperty("tfs_upid")) {
userProfileId = query.tfs_upid;
console.log("userProfileId = ", userProfileId);
//check whether user was already activated or not, else: new activation
user_data = await wixData
.query("userprofile_ldev")
.eq("_id", userProfileId) //get id from the session.
.find();
console.log(user_data._items[0]);
console.log("status:");
console.log(user_data._items[0].status);
if (user_data._items[0].status === "Registered") {
//first visit
console.log("First visit!");
firstVisit = true;
user_data._items[0].status = "Activated"; // updated last name
wixData.update("userprofile_ldev", user_data._items[0]);
} else if (user_data._items[0].status === "Activated") {
//returning
console.log("Returning visitor!");
}
}
}
}
if(firstVisit){
//doSomething
}
Unfortunately, when I run my code while user_data._items[0].status still equals ‘Registered’ in the collection, he’s not seen as a first time visitor. I believe this has to do with the fact that my query, which updates the status to ‘Activated’, runs before the check user_data._items[0].status === “Registered”
What’s the best way to get around this?
Sorry, but I don’t understand what query is. Where is it set?
Do you see the First visit and Returning visitor displayed in the console? If so, you are correct and the variable firstVisit is probably being checked before it is set.
If you are handling a Promise somewhere (maybe not in the code that you’ve shown?), then it’s very likely that firstVisit is being set only after you are checking it.
If you are having trouble with Promise, see the following for more information:
Hi @yisrael-wix ,
I added the declaration of query.
No, I only see “Returning visitor!” logged by the console, even when its the user’s first visit (onReady, user_data . _items [ 0 ]. status equals “Registered” on database level).
Hence, somehow user_data . _items [ 0 ]. status gets set to " Activated " too early, otherwise it wold log " First visit!" .This can only happen if
user_data._items[0].status ="Activated"; wixData.update("userprofile_ldev", user_data._items[0]);
gets executed before following if structure:
if(user_data._items[0].status ==="Registered"){
elseif(user_data._items[0].status ==="Activated"){
}
@vervoortyves You also need to handle the Promise returned by the update. For example:
await wixData.update("userprofile_ldev", user_data._items[0]);
I don’t know what user_data_items is, but you need to provide the update() function with an object containing all of the item fields, including the value to be updated. See the update() API documentation.
Your declaration of the variable query sets it to an empty query. The properties in the query itself are not necessarily exposed to Velo code. I really don’t know if the statements checking on .hasOwn() will work.
What you should be doing is to perform a query based on certain conditions which will allow you to determine if the visitor is a first time or returning user. See the WixDataQuery API for details on how to build a query to attain the results that you want. There a plenty of data examples that you can inspect to see how various queries are performed.
@yisrael-wix my update function does what it is supposed to do. Also I’ve rewritten my entire code now with by using asynchronous code instead. Nothing changes: the update happens too early. I have the feeling the asynchronous communication between database layer and application layer is causing the issue. I’ve already figured out a solution to get around it.
@yisrael-wix your explanation does not make any sense. Query contains wixLocation data from the URL. I basically parse my URL using hasOwnProperty on wixLocation.query which is an object.
@vervoortyves Wow! You’re right - my explanation doesn’t make sense. I was thinking of WixData query, not WixLocation query. Sorry.
I’ll take a look at this again tomorrow when I’m not so foggy-headed.
Please post the URL and explain where and how to see the problem. Maybe if I see code in its natural environment it’ll provide context and I’ll see something.
@yisrael-wix thanks, much appreciated.
Try: https://thefashionsocietyh.editorx.io/tfs-dev-x/welcome?tfs_upid=b019ffac-4eda-4593-bde4-7f3448e14ae2&utm_source=Individual+Shopper&utm_campaign=d2b577fa21-URBEXCO_TFS_INDIVIDUAL_SHOPPER_WELCOME&utm_medium=email&utm_term=0_2447fe98f0-d2b577fa21-407633493&mc_cid=d2b577fa21&mc_eid=19aea8a42a
As you can see, I’ve re-written everything using asynchronous logic and functions.
Added a comment on line 45 which is where the issue ‘starts’. In short: the initial condition is that in my database, the user is assigned status ‘Registered’ - hence when he accesses my page, he should be seen as a first time visitor. On execution of checkQuery() this status should be displayed. Once activateUser() is run, the status should change to ‘Activated’ and a database update is done.
Now, when commenting out activateUser(), checkQuery() indeed prints the right status to the console. However, when activateUser() is not commented out, checkQuery() already prints ‘Activated’, where it should still be ‘Registered’ as activateUser() wasn’t executed yet.
Beware, to execute another test, e.g. when you refresh the page, you’ll have to set the field ‘status’ in collection UserProfile back to ‘Registered’.
In the checkQuery() function, you have the following:
if(user_data._items[0].status === "Registered"){
firstVisit = true;
} else if(user_data._items[0].status === "Activated"){
firstVisit = false;
}
A wix-data query returns items in the returned user_data object, not _items. The code should be:
if(user_data.items[0].status === "Registered"){
firstVisit = true;
} else if(user_data.items[0].status === "Activated"){
firstVisit = false;
}
I hope that helps. This page alone has over 450 lines of code. If you continue to have issues, please understand that we are unable to debug or rewrite complex code and page configurations. If you feel that there is a bug in Velo, then please try to create a test page with the minimum scenario in which the problem appears in order to help us investigate the issue properly.
@yisrael-wix OK, but that’s not the issue… Here’s a MWE of 140 lines:
$w.onReady(async function() {
firstVisit = await checkQuery(wixLocation.query);
if (firstVisit !== undefined) {
if (firstVisit === true) {
console.log("User wasn't activated yet");
// --- START ISSUE
// When this part of the code is activated, above function checkQuery() already has user_data.items[0].status equal to 'Activated' instead of 'Registered'. When this part is not activated, user_data.items[0].status equals 'Registered' (as expected)
await activateUser();
// --- END ISSUE
} else {
console.log("Active user");
}
}
if (user_data !== undefined) {
console.log("Check invites");
await checkInvites();
}
membership = await checkMembership(); //memberId or not?
console.log("Membership: ", membership);
if (membership !== undefined) {
if (!membership) {
console.log("Not a full member yet");
} else {
console.log("Already a full member");
}
}
async function checkInvites() {
//check invites
console.log(user_data.items[0].invite_data);
//count the number of links generated
var linksGenerated = user_data.items[0].invite_data.filter(function(e) {
if (e.link !== "") {
return e;
}
});
console.log("links generated:");
console.log(linksGenerated);
console.log("number of links generated:");
console.log(Object.keys(linksGenerated).length);
if (Object.keys(linksGenerated).length < 3) {
//
var requiredReferrals = 3 - Object.keys(linksGenerated).length;
$w("#box223").expand();
$w("#box223").show();
$w("#text280").show();
$w("#text280").text =
"You need to send " + requiredReferrals + " more invites";
} else {
$w("#box223").collapse();
$w("#box223").hide();
$w("#text280").hide();
membership = await checkMembership();
if (!membership) {
console.log("Membership: ", membership);
console.log("openLightbox()");
wixWindow.openLightbox("Create password");
}
}
}
async function checkQuery(query) {
console.log("query:");
console.log(query);
if (
query.hasOwnProperty("mc_cid") &&
query.hasOwnProperty("mc_eid") &&
query.hasOwnProperty("utm_campaign") &&
query.hasOwnProperty("utm_medium") &&
query.hasOwnProperty("utm_source") &&
query.hasOwnProperty("utm_term")
) {
if (
query.mc_cid === "d2b577fa21" &&
query.mc_eid === "19aea8a42a" &&
query.utm_campaign ===
"d2b577fa21-URBEXCO_TFS_INDIVIDUAL_SHOPPER_WELCOME" &&
query.utm_medium === "email" &&
query.utm_source === "Individual Shopper" &&
query.utm_term === "0_2447fe98f0-d2b577fa21-407633493"
) {
console.log("accesspoint: e-mail");
if (query.hasOwnProperty("tfs_upid")) {
userProfileId = query.tfs_upid;
console.log("userProfileId = ", userProfileId);
//check whether user was already activated or not, else: new activation
user_data = await wixData
.query("userprofile_ldev")
.eq("_id", userProfileId) //get id from the session.
.find();
console.log(user_data.items[0]);
console.log("status:");
console.log(user_data.items[0].status);
if (user_data.items[0].status === "Registered") {
firstVisit = true;
} else if (user_data.items[0].status === "Activated") {
firstVisit = false;
}
}
session.setItem("str_user_data", JSON.stringify(user_data.items[0]));
}
} else {
console.log("Not allowed!");
}
return firstVisit;
}
async function checkMembership() {
if (user_data !== undefined) {
if (user_data.items[0].hasOwnProperty("memberId")) {
if (user_data.items[0].memberId !== "") {
//User has account
console.log("User already has an account");
membership = true;
} else {
//NOK
membership = false;
}
} else {
//NOK
membership = false;
}
return membership;
}
}
async function activateUser() {
console.log(user_data.items[0].status);
user_data.items[0].status = "Activated";
await wixData
.update("userprofile_ldev", user_data.items[0])
.then((res) => {
console.log("push_res");
console.log(res);
})
.catch((err) => {
let errorMsg = err;
});
}
});
@vervoortyves I’m sorry, but another 140 lines of complex code. I just don’t understand it.
You are apparently not correctly updating the member profile record. Why? I really don’t know. The checkQuery() function has a complex if statement with a number of conditions being checked that I have no idea what they are or why you are checking them.
Again, please understand that we are unable to debug or rewrite complex code and page configurations. If you feel that there is a bug in Velo, then please try to create a test page with a minimum scenario of the problem. I suggest rewriting your code, starting with simple conditions, testing, and then adding other conditions a little at a time.
One possibility is that your code might be running twice - once server-side, and the second time browser. To prevent Server Side Rendering, check the current environment and only run your code browser-side:
import wixWindow from 'wix-window';
$w.onReady(function () {
if (wixWindow.rendering.env === "browser") {
// put your code in here
}
} );
I hope this helps.
I’m really not sure about this since you are checking the URL query, and I’m not sure if your code does anything with that during server-side rendering.
@yisrael-wix nevermind, implemented a workaround.
Good to hear. What was the workaround?
@yisrael-wix dirty solution. Replaced
$w.onReady(async function(){
firstVisit = await checkQuery(wixLocation.query);
if(firstVisit !== undefined){
if(firstVisit === true){
console.log("User wasn't activated yet");
// --- START ISSUE// When this part of the code is activated, above function checkQuery() already has user_data.items[0].status equal to 'Activated' instead of 'Registered'. When this part is not activated, user_data.items[0].status equals 'Registered' (as expected)
await activateUser();// --- END ISSUE
} else {
console.log("Active user");
}
}
});
by
$w.onReady(async function(){
firstVisit = await checkQuery(wixLocation.query);
if(firstVisit !== undefined){
if(firstVisit === true){
console.log("User wasn't activated yet");
} else {
console.log("Active user");
}
}
//Handle for above issue
$w("#page1").onViewportEnter(async(event) => {
if(firstVisit){
await activateUser()
}
firstVisit = false;
});
});
@vervoortyves Seems like cheating. But I like it!
I’d love to know what the problem was, but I just kept getting lost in the code. Glad you got it working. Hopefully you’ll find a “real” solution while taking a shower or quaffing a brew.
Ya know, looking at the above code snippets got me thinking. Your workaround seems to indicate that there’s an issue with synchronicity. Perhaps there was an issue with the code running twice? That is, server-side and browser-side. Did you try checking if wixWindow . rendering . env is equal to browser ?
Anyhow, if you figure it out, please let me know. 