I’m having trouble with
BulkSave works in preview, but not live
Working in
Dev Mode
What I’m trying to do
Make it work in live as well as preview? I tried it as an automation too: trigger was scheduled time, action was velo code. But it did an update instead of save, despite me having the code set as save.
What I’ve tried so far
Tried adjusting permissions for the CMS but that didn’t seem to help.
Extra context
// Velo API Reference: https://www.wix.com/velo/reference/api-overview/introduction
import wixData from 'wix-data';
$w.onReady(function () {
async function syncAggregatedData() {
// 1. Get the aggregated results (sum of points per horse/rider and division)
const returnresults = await wixData.aggregate("2026highpoints")
.group("horseId", "division")
.limit(250)
.sum("pointsEarned")
.run()
.then(async (sumAgg) => {
const aggresults = sumAgg.items; // Array of horseId, division, pointsEarnedSum
const horseidentity = aggresults.map(item => item.horseId);
const divisionidentity = aggresults.map(item => item.division);
// 2. Query target collection for matching items
const horseref1 = await wixData.query("HorseReference") //get the first division _id listed for the horse
.isNotEmpty("firstDivision")
.limit(250)
.find();
// 3. Match and prepare items for updating/save
const itemsToSave = horseref1.items.map(horseinfo => {
// Find matching aggregate for the horse
const matchdivone = aggresults.find(agg =>
agg.horseId === horseinfo._id &&
agg.division === horseinfo.firstDivision);
const matchdivtwo = aggresults.find(agg =>
agg.horseId === horseinfo._id &&
agg.division === horseinfo.secondDivision);
if (matchdivone) {
horseinfo.firstDivisionPoints = matchdivone.pointsEarnedSum;
if (matchdivtwo) {
horseinfo.secondDivisionPoints = matchdivtwo.pointsEarnedSum;
}
return horseinfo;
}
}).filter(item => item !== undefined);
return { itemsToSave }
});
// 4. Bulk save
if (returnresults.itemsToSave.length > 0) {
return wixData.bulkSave("HorseReference", returnresults.itemsToSave);
}
}
$w('#button1').onClick(syncAggregatedData);
});
The most likely cause of this is CMS permissions. What do you have them set to at the moment?
It’s also worth noting that it’s generally recommended to have data operations run in backend code via webMethod() - Velo Wix Web Module Introduction | Velo - especially when it comes to updating/saving data to ensure only those who are meant to be able to do this can.
Hi, @Lauren_Cintas !!
Actually, wixData.save() (and bulkSave) is designed to do both: it updates the item if it already exists, and inserts it if it’s new. 
I had forgotten that… I didn’t think you needed to send all of the info that you want to stay the same through the save/bulksave. I thought that was only if you did the update. When I did the automation, it saved the aggregate as planned but wiped out all the other columns.
I tried setting it to collaborators, and making sure I was logged in as said collaborator. I do not recall if I tried it when set to “everyone”. I wanted to have it run as an “afterUpdate”, but I have something else set to do that and I’m not sure how to have them both go and not interfere with each other, since the purpose of this aggregation is to update a different collection, and what I have in the afterUpdate now is for the collection being updated.
Oh, okay. I tried setting the permissions to everyone and it works now. I’d rather combine it with the afterUpdate for the 2026 highpoints but don’t want to mess up what’s in there.
import wixData from 'wix-data';
export async function _2026highpoints_afterUpdate(item, context) {
let hookContext = context;
//TODO: write your code here...
if (item.placing == 1) {
const points = 6;
if (item.championshipStake == true && item.showName != "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == false && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == true && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 4;
} else {
item.pointsEarned = points;
}
} else if (item.placing == 2) {
const points = 5;
if (item.championshipStake == true && item.showName != "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == false && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == true && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 4;
} else {
item.pointsEarned = points;
}
} else if (item.placing == 3) {
const points = 4;
if (item.championshipStake == true && item.showName != "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == false && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == true && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 4;
} else {
item.pointsEarned = points;
}
} else if (item.placing == 4) {
const points = 3;
if (item.championshipStake == true && item.showName != "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == false && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == true && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 4;
} else {
item.pointsEarned = points;
}
} else if (item.placing == 5) {
const points = 2;
if (item.championshipStake == true && item.showName != "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == false && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == true && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 4;
} else {
item.pointsEarned = points;
}
} else if (item.placing == 6) {
const points = 1;
if (item.championshipStake == true && item.showName != "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == false && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 2;
} else if (item.championshipStake == true && item.showName == "6c731295-ff52-43ce-a202-2e9f5edb9af6") {
item.pointsEarned = points * 4;
} else {
item.pointsEarned = points;
}
}
return item;
}