EDIT: Solved, with solution and code sample in a comment below.
I’m trying to use a repeater to display what a user has access to based on their role. I use the code below to get the current user’s member role, then use a filter to show the items they have access to.
The code works if a user only has access to one item, but the problem is that it if a user has access to 2 or more items, the filter only returns one instead of multiple.
How can I change this filter setup to display multiple items to users with multiple roles? Or is there a simpler / more elegant way to accomplish this? I’m assuming my logic/setup is faulty. I’m by no means a pro, but I’ve been searching the forum for days and I feel like I’ve gotten so close! I’ll take any advice/references I can get.
My setup:
• Three strips, all collapsed on load. One strip (“stripLoading”) says “loading” and loads immediately, one strip (“repeaterStrip”) contains the repeater and expands when the filter is finished, one strip (“stripNoOrders”) says “No Orders” and expands if the user has no role.
• A repeater with elements linked to a dataset
• A database named “ocDataset”
• A field in the database named “roleFilter” with tags for each item
• Code to filter the data based on the “roleFilter” tags
My code: (shortened; I have 7 roles total)
import wixUsers from 'wix-users';
import wixWindow from 'wix-window';
import wixLocation from 'wix-location';
import wixData from 'wix-data';
let user = wixUsers.currentUser;
$w.onReady(function () {
$w('#stripLoading').expand();
if (user.loggedIn) {
user.getRoles()
.then((roles) => {
if (roles.some(r => r.name === "EXP Mosaic Mirror")) {
$w("#ocDataset").setFilter(wixData.filter()
.eq("roleFilter", "expMM")
)
.then(() => {
console.log("Dataset is now filtered");
})
.catch((err) => {
console.log(err);
});
$w('#stripLoading').collapse();
$w('#repeaterStrip').expand();
} else {
$w('#stripLoading').collapse();
$w('#stripNoOrders').expand();
}
if (roles.some(r => r.name === "EXP Treasure Box")) {
$w("#ocDataset").setFilter(wixData.filter()
.eq("roleFilter", "expTB")
)
.then(() => {
console.log("Dataset is now filtered");
})
.catch((err) => {
console.log(err);
});
$w('#stripLoading').collapse();
$w('#repeaterStrip').expand();
} else {
$w('#stripLoading').collapse();
$w('#stripNoOrders').expand();
}
});
}
})
Thanks so much for your reply and suggestion! I tweaked the code and it works great to show the variations possible for these 2 roles.
Followup question: I have 7+ roles. With this setup, would I have to manually account for each possible combination of roles? Or am I misinterpreting the code?
i.e. Would I have to create code for: Role1 && Role2 Role1 && Role2 && Role3 Role1 && Role3 Role1 && Role3 && Role4 etc…
(If my math is correct there are over 5000 possible combinations of 7 different roles )
@jonatandor35 Awesome! Thanks so much for helping me work through this! We’re getting so close. I’m just getting an error that “r” is undefined. My page code is below if you could help me out:
import wixUsers from 'wix-users';
import wixWindow from 'wix-window';
import wixLocation from 'wix-location';
import wixData from 'wix-data';
let user = wixUsers.currentUser;
$w.onReady(function () {
$w('#stripLoading').expand();
$w('#repeaterStrip').collapse();
if (user.loggedIn) {
user.getRoles()
.then(() => {
let roleValues = [
{role: "EXP Treasure Box", value: "expTB" },
{role: "EXP Treasure Box", value: "expMM" },
{role: "ncGrade1", value: "nc1" },
{role: "ncGrade2", value: "nc2" },
] //etc
let filter = wixData.filter();
let roles = r.name; // 'r' is not defined
let relevantValues = roles.map(e => roleValues.find(i => i.role === e).value);
filter = filter.eq("roleFilter", relevantValues[0]);
relevantValues.shift();
if (relevantValues.length > 0) {
relevantValues.forEach(e => {
filter = filter.or(wixData.filter().eq("roleFilter", e));
})
}
$w("#ocDataset").setFilter(filter).then(() => {
console.log("filtered");
ordersView();
})
.catch((err) => {
console.log(err);
});
})
}
})
I know previously I had defined it like so:
if (roles.some(r => r.name === "Admin"))
Where in this new code should it be defined? Again thank you for all your help.
@jonatandor35 I really appreciate your guidance with this! I made the fix and get no more errors in the Editor, but on the live site the code is not working…
I ran some console logs to check where it gets stuck and I get some errors around the “let relevantValues = roles.map” line. Any ideas for a fix?
@jonatandor35 I made the change and still no luck! I’m testing with a user that has several roles, but the repeater shows all roles instead of being filtered, and the code doesn’t move beyond the “let relevantValues = roles.map” line.
When I test on a user with no roles, the “if (r.length > 0) … else” works as expected to show the elements I want it to.
@jonatandor35 No worries, you’re helping me learn a lot! I’m a bit outside my scope of knowledge with loops and maps, so I’m enjoying the crash-course. I made the change but unfortunately I encounter the same problem, except now with a different error in the console:
Things I’ve done:
Changing the roleFilter field in the database to Text instead of Tags
Checking the permissions on the dataset
Double-checking that all IDs, role names, and field values are exact
Testing on a user with several combinations of multiple roles, multiple times
Including all roles in the roleValues array
By the way, instead of console.log(“some string”), you should log the relevant variable, so you’ll be able to locate the error. For example: console.log(roles)
For anyone trying to accomplish the same thing, here’s my setup.
Shoutout to @jonatandor35 , a true Corvid Master, for the amazing help figuring out the code. Obviously tweak it to fit your setup.
• Three strips, all collapsed on load. One strip (“stripLoading”) says “loading” and loads immediately, one strip (“repeaterStrip”) contains the repeater and expands when the filter is finished, one strip (“stripNoOrders”) says “No Orders” and expands if the user has no role.
• Database with your fields, then add a field to filter by. Mine is “roleFilter” and I have tag values that correspond to each of my Roles. (With “admin” in all, so Admin get access to everything)
import wixUsers from 'wix-users';
import wixWindow from 'wix-window';
import wixLocation from 'wix-location';
import wixData from 'wix-data';
let user = wixUsers.currentUser;
$w.onReady(function () {
$w('#stripLoading').expand();
$w('#repeaterStrip').collapse();
//collapse repeater until filter is complete
if (user.loggedIn) {
user.getRoles()
.then(r => {
if (r.length > 0) {
let roleValues = [
// role = role name, value = value in database field
{role: "Role Name 1", value: "expTB" },
// Change according to your Role names, and database field values
{ role: "Role Name 2", value: "expMM" },
{ role: "Role Name 3", value: "expSS" },
{ role: "Admin", value: "admin" },
] //etc, for as many roles as you have
console.log("roles defined");
let filter = wixData.filter();
let roles = r.map(e => e.name);
roles = roles.filter(e => roleValues.some(i => i.role === e));
console.log("roles", roles);
let relevantValues = roles.map(e => roleValues.find(i => i.role === e).value);
console.log("relevant values", relevantValues);
filter = filter.eq("roleFilter", relevantValues[0]);
//"roleFilter" is the database field I'm filtering by.
relevantValues.shift();
if (relevantValues.length > 0) {
relevantValues.forEach(e => {
filter = filter.or(wixData.filter().eq("roleFilter", e));
})
}
$w("#ocDataset").setFilter(filter).then(() => {
console.log("Dataset is filtered");
ordersView(); //function to show repeater
})
} else {
noOrdersView();
//function if user has no roles
}
})
}
})
function ordersView() {//function if user has roles
$w('#repeaterStrip').expand();
$w('#stripLoading').collapse();
}
function noOrdersView() {//function if user has NO roles
$w('#stripLoading').collapse();
$w('#stripNoOrders').expand();
}
I am new to wix corvid and created a Dynamic page with items to be filtered between a certain months shown below.
I would like to add a badges filter so only members with specific badges can see certain items set in the database. Example members with bronx badge can only see bronx (tag or filtered) pages on certain months I followed the same steps and created a tag values and enter roles to be filtered but can’t use the code being discuss.
User A - Badge is set to “Bronx”
User B - Badge is set to “Brooklyn”
User C - Badge is set to “Manhattan”
User D - Badge is set to “Queens”
User E - Badge is set to “StatenIs”
User F - Badge is set to “Bronx” & “Brooklyn” & “Queens”
The dynamic page set with a Filter repeater based on Member Role with in the database.
Bronx Badge - can only see filter Bronx (items/pages)
Brooklyn Badge - can only see filter Brooklyn (items/pages)
Manhattan Badge - can only see filter Manhattan (items/pages)
Queens Badge - can only see filter Queens (items/pages)
StatenIsBadge - can only see filter StatenIs (items/pages)
User F - Can see 3 filters “Bronx” & “Brooklyn” & “Queens” (items/pages)