I see there are a few similar questions asked with answers that don’t seem to lead me to how to solve this issue.
Problem: We have a large data set of dogs for adoption (and that have been adopted) that we have mostly finished moving to be dynamic data rather than static web pages. The Primary Field is currently assigned to the dog name, but I just noticed that two live dogs have the same name and are directing to the same page (the most recent of the two dogs).
Attempt 1 to solve: Even though it’s ugly, I went to change the primary field to be the ID field to avid this, and as I’ve discovered, you can’t use the ID field in this case. Which seems insane to me, but it is what it is.
Roadblock to a likely reasonable solution: Our volunteers that enter dog data are not always tech savvy, so I can’t ask them to do a search for a dog name and add a unique slug name in the data set. It’s just not foolproof enough.
What are my options? What I’d love to do is have a non-user accessible field that just auto-increments a number after the dog name. I’m not finding anything like that… perhaps I’m not looking hard enough? I’ve read about calculated fields, but I’m not seeing anything that jumps out at me.
You can create another field called slug, basically it’s a field that has the dog name but with an added number, for example, there are two dogs called “Poppy”, the first one will has a slug ‘poppy’ and the second one will has a slug ‘poppy-1’ to avoid URL mismatch. All URLs must be unique.
You can write a code and run it (only once) to fix this issue by querying each name to see how many duplicates there are out there, and update them accordingly to have an increment value, here’s an example:
let dogs = await wixData.query('Dogs').limit(1000).find();
for (let i = 0; i < dogs.length; i++) {
let dog = dogs.items[i];
// Now search for duplicates;
let duplicates = await wixData.query('Dogs).eq('name', dog.name).find();
if (duplicates.length > 0) {
// Keep one and update the others
for (let j = 1;j < duplicates.totalCount;j++) {
let item = duplicates.items[0];
item.slug = `${item.name.toLowerCase()}-${j}`;
await wixData.update('Dogs', item);
}
} else {
// Create a slug for the unique name
dog.slug = dog.name.toLowerCase();
}
}
The above code needs to run only once to fix the old names, but for future names you need to run a beforeInsert Hook to edit the slug to a unique value. Use the same method to detect duplicates and give a unique slug.
export async function Dogs_beforeInsert(item, context) {
let duplicates = await wixData.query('Dogs').eq('name', item.name).find();
if (duplicates.totalCount> 0) {
item.slug = `${item.name.toLowerCase()}-${totalCount+1}`
}
return item;
}
Woah! I had discovered Hooks while on a call after posting this, but wow, you just did my work for me! I’m both grateful, and feel super-guilty.
This is a MASSIVE help, because while I’d started the hook (I was doing it as an afterInsert, so yours corrected me from doing at the wrong stage), I was also going to do the enumeration of the existing dog slugs by hand.