Create a new item with identical field values as the last saved one

Hello,

I hope you are doing well.

For the moment I wrote some lines of code that allows members to record field value for a currentItem (1) before saving that currentItem (2) in a dataset and moving to the next one. So far everything works well and I use the following lines for that:

  1. $w(‘mydataset’).setFieldValue(‘fieldname’, value);
  2. $w(‘mydataset’).save();

Now I am looking to prepare the next item, by prefilling its values with the ones saved by the member for the last currentItem (when he triggers the save event). Do you know the lines of code for that ?

I already tried with the .getItem but have not been able to retrieve any information.

thank you in advance,
Nat

From https://www.wix.com/velo/reference/wix-data/wixdataaggregate/max
You could look at getting the maximum (.MAX) creation date _createdDate. Use the below as an example. Or you could keep a running counter in a field.

import wixData from 'wix-data';
2
3// ...
4
5wixData.aggregate("PopulationData")
6  .group("state", "year")
7  .max("population")
8  .run()
9  .then( (results) => {
10    if (results.items.length > 0) {
11      let items = results.items;        // see below
12      let numItems = results.length;    // 6
13      let hasNext = results.hasNext();  // false
14    } else {
15      // handle case where no matching items found
16    }
17  } )
18  .catch( (error) => {
19    let errorMsg = error.message;
20    let code = error.code;
21  } );

Hello Kyle,

Thank you very much for your response. I feel that I already made a step forward thanks to you as I am now able to retrieve not the last item saved but the one before (second to last).

I followed your suggestion and went to the link you provided. I saw a little bit below that it was possible to filter. So I added a filter (by member) in order to retrieve only the itmes saved by the member himself and put max _createdDate to get the last one.

Do you think the reason why I am retrieving the penultimate and not the last one can be due to to the time between the saving action and the retrieving of information ?

Eventually I guess that my last step now is to put the field values of the last item saved to the new currentItem.

Do you know where should I place the following and what’s the correction to be brought to these lines ? I tried to put them just after the console.log but it does not work. I also tried results.member…
$w ( ‘#datasetLUSimulation’ ). setFieldValue ( “member” , items.member )
$w ( ‘#datasetLUSimulation’ ). setFieldValue ( “luPr” , items.luPr )

Again, thank you

const filter = wixData.filter().eq("member", user.id);

wixData.aggregate("LuSimulation")
  .filter(filter)
  .max("_createdDate")
  .limit(1)
  .run()
  .then( (results) => {
    if (results.items.length > 0) {
      let items = results.items;
      let numItems = results.length;
      let hasNext = results.hasNext();

    console.log(items)
    } else {
      // handle case where no matching items found
    }
  } )
  .catch( (error) => {
    let errorMsg = error.message;
    let code = error.code;
  } );

}

No prob. The next step is to probably play with hooks and https://www.wix.com/velo/reference/wix-data/hooks/beforeinsert

The beforeInsert one. So you are about to create a record, then this event fires before the record has been created. Here you get the last record which would be max(created date) which would be the last record as no new records would have been created. This is a back end function.
If you create the record first and then fetch, then you would be getting the second to last one. Will leave you with that for the moment as if you havent dealt with backend functions, hooks and the like there’s a bit to get your head around. Suggestion is read up on how to do the before Insert and put some debugging in place in that function. Whilst a little dated, this post explains the hook well.

https://www.wix.com/velo/forum/coding-with-velo/numbered-index

I think once you get your head around these, the rest will fall into place for you.
All the best.

Hello,

I found the links you sent very instructive and have been able to make a hook works nicely. I did not know about the hook functionality before.

Now when a member push the first time on the save button after choosing the vales, an afterInsert is triggered in the backend and a new record with the same value as the one just entered is saved. Meaning the problem of the second to last is also resolved as I have now to identical items saved.

My last point is that using an insert in the hook, forces the saving exercise.
I would like to block the automatic saving exercise made by he thook and only prepare the item with the values from the previous one.
Like this the user has a prefilled item, can change only one value and push again on the button to finalize the insertion / saving of the new item (otherwise the automatic saving of the insertion create a duplicate).

I searched for some parameters that could block the automatic saving in the insert function but did not find one useful for this exercise.

I also looked at another function, but feel that all save automatically.

Did you face such point before ? Do you know a way to do this ?

import wixData from 'wix-data';

export function LuSimu_afterInsert(item, context) {
    
    let options = {
        "suppressHooks": true
    };
 
    let newItem = {
         "luPr": item.luPr,
         "luDi": item.luDi,
         "luRe": item.luRe,
         "luCa": item.luCa,
    }

    wixData.insert("LuSimu", newItem, options)
        .then((results) => {
            console.log("done adding new item", results)
        })
        .catch((err) => {
            console.log(err);
        });
    return newItem;
}

I’ll give my bit here, cause sometimes its way simpler than we imagine.

After you use the .save() method in you dataset, you effectively have the object that was inserted as a return from the method itself, you can use the object to pre-fill anything you want and select any changes BEFORE even saving it. You don’t need to use the hook (if I understood what you need).

const preFilledItem = await $w("mydataset").save()
console.log(preFilledItem)

Put this code inside the action using an async method and try it.

Example:

$w.onReady(() => {
    $w('#btnLike').onClick(async () => { //Asynchronous method with the word async.
        $w('#dataset1').setFieldValue("like", 1)
        const likedObj = await $w('#dataset1').save()
        console.log(likedObj)
    })
})

Nice idea. I think that would work if there was an immediate need to fill in the form for example, but if it happened two days later from another user it may not work. I it is immediate I think it is an elegant solution you propose.

What about a beforeInsert hook? There are probably a number of ways around this if Bruno’s method didn’t suit. Maybe creating the new record in a temporary table. Now you’re in the world of hooks and events there’s no turning back from the black hole now :slight_smile: