Incrementally update a number field

Hiya folks,
I’m trying to create a progress indicator that tracks a user’s completion of tasks that they can complete in any order they want.

Basically, each page has a prompt for a user to fill in. Their answers get submitted to a single database. In that database I have the number of expected answers in a field to be the target value, and an answered questions numeric field which will be used for the ‘value’. (this is specific per user)

On submit, I want to incrementally add to the answered questions field.

My high level thought on flow:

  1. On page load:

  2. check the answered questions field for user in my database and update

  3. check if the current prompt field is blank for logged in user

  4. If yes (then I will need to mark it as done when they submit their answer):

  5. On Save_click add +1 to answered questions field

  6. Update progress bar

  7. If no (then I just need to let them update their answer, but don’t need to do anything to the answered questions field)… then just save updated prompt answer

I almost accomplished this with the following test code…BUT that update creates an additional object in the item array:

I’m sure there is an easier way to accomplish this?

import wixData from ‘wix-data’ ;
import wixUsers from ‘wix-users’ ;
let userId = wixUsers. currentUser. id;
export function button6_click(event) {
wixData. query( “News” )
.eq( “_owner” , userId)
.find()
.then( (results) => {
let items = results.items;
let item = items[ 0 ];
let p3field = item. p3HavingYouWasImportantToUsBecause;
let ansQ = item. p3AnsweredPrompt;
console. log(items);
if (p3field. length > 0 ) {
if (ansQ === undefined){
let updatedCount = 1 ;
let toUpdate = {
“_owner” : userId,
“p3AnsweredPrompt” : updatedCount,
};
wixData. insert( “News” , toUpdate);
console. log(updatedCount);
} else {
let updatedCount = ansQ + 1 ;
let toUpdate = {
“_owner” : userId,
“p3AnsweredPrompt” : updatedCount,
};
wixData. insert( “News” , toUpdate);
}
} else {
console. log( ‘um, i did this backwards’ );
}
} );
}

I’m assuming data insert is the wrong way to go about this? Thanks for your help!

Hey Josh,

If you’re looking to update the same item record that you pulled from the News DB, you could use the wixData.save method instead to handle the incrementing. It’s a convenience method that figures out if the record exists using the _id field. To use it, you should pass back the entire object. This could look something like this:

//...
 		if(p3field. length > 0) {
 			if(ansQ === undefined){
				 let updatedCount = 1;
				 let toUpdate = {
					 "_owner": userId,
					 "p3AnsweredPrompt": updatedCount,
					...item //This little piece here adds the other fields back to your object
                   	 };
                		wixData.save("News", toUpdate);
                		console. log(updatedCount);
            		 } else {
 				let updatedCount = ansQ + 1;
 				let toUpdate = {
 				"_owner": userId,
				 "p3AnsweredPrompt": updatedCount,
				  ...item
                   	 	 };
                		wixData.save("News", toUpdate);
             	         }
                }
//...


You can also condense the code a little bit using a ternary operator to handle the updatedCount variable, which will also make it a little more user friendly.

//... Same code as above
 		if(p3field. length > 0) {
 				let toUpdate = {
 				"_owner": userId,
				 "p3AnsweredPrompt": ansQ===undefined?1:ansQ+1,
				  ...item
                   	 	 };
                		wixData.save("News", toUpdate);
             	         }
                }
//...

N.B., it’s very important that you pass the data that was in the original object back to wixData.save, otherwise it will overwrite that old record with only what you send back in.

Aw man, this is beautiful. Thank you for the thoughtful response and explanation. I will test tonight and report back!

No problem! Let me know how it goes.

Chris, this works great. Appreciate the help. One additional question…

I want to copy this code across pages so I’m hoping to make it as dynamic as possible.

The two variables that will change across pages are the prompt field that is being updated by the user’s text answer, as well as the answered questions field which we connected to here (the prompts are chapter based so this will change every 5 or so prompts).

Is there a way I can pull the data field I’m working from the text box I have on the page and set it as a variable on ready?

If I could do something like that then I could make the code basically say:

  1. Okay what page are we on?
  2. Ah, we’re updating ‘p3HavingYouWasImportantToUsBecause’ and updating count on ‘p3AnsweredPrompt’…let’s set those as variables.
  3. On save, fieldToUpdate = variable set in #2 and countToUpdate = other variable set in #2

Does that make sense? Thanks for your help!

More simply, I have a text input and a text box on the page that are connected to my data set. Any way I can identify via code what field one is connected to and set that as my prompt field to be updated?

@chris-derrell alright, the ternary handler works, however when I set my fields that i want to update its not carrying through. I am posting to console.log to check and it’s just grabbing what is currently available in the db…not result of the operator:


my code:

export function button6_click(event) {
    console.log(userId);
    wixData.query("News")
    .eq("_owner", userId)
    .find()
    .then( (results) => {
 let items = results.items;
 let item = items[0];
 let promptField = results.items[0][currentPrompt[0]];
 let ansQ = results.items[0][answeredPrompt[0]];
        console.log('here:');
        console.log(promptField);
        console.log('ansQ:');
        console.log(ansQ);
        console.log('ansQupdate:');
        console.log(ansQupdate);
 if(promptField.length > 0) {
            console.log('not empty');
 let toUpdate = {
 "_owner": userId,
 "p3AnsweredPrompt": ansQ===undefined?18:ansQ+21,
                ...item
            };
            console.log('toUpdate:');
            console.log(toUpdate);
 // wixData.save("News", toUpdate);
        }
    } );
}

in the above, “p3AnsweredPrompt” in the current DB is ‘2’, so that is what shows in the log, not ‘24’.