Copy items from one collection to another

Hi,

I found a bug were after hooks affect the original item. That should not happen according to the doc

Because the afterUpdate hook is called after the update() is executed, it cannot affect the item that is being updated in the collection. It can only affect the item returned by update() .
but as you can see in the video here . It does… badly.

here is the data code for data.js

import wixData from 'wix-data';

let options = {
 "suppressAuth": true,
 "suppressHooks": true
};

export function Projects_afterInsert(item, context) {
    item.originalId = item._id;
    delete item._id;
    return wixData.insert('copy', item, options);
}

export function Projects_afterUpdate(item, context) {
     return wixData.query('copy').eq('originalId',                item._id).find().then(result => {
         item._id = result.items[0]._id;
         return wixData.update('copy', item, options);
    });
}

Demo website

  1. Could you confirm that behaviour is a bug?

  2. If it’s, do you plan on fixing this soon?

Thx, @Sheyla Ruiz, @Yisrael (Wix)

#bug, #wixData

1 Like

Can someone from Wix review this?

Hi, thank you for reporting the issue. We have forwarded it to our developers and will let you know as soon as we have any updates on this.

hey, @plomteuxquentin

what is the idea behind

   item.originalId = item._id;
   delete item._id;

lines?

The cause of such behavior is in afterInsert hook (not afterUpdate). After first insert you are deleting the _id (the unique key which is used for unique identification of a data entry) so every further update from the system perspective is a new insert (because there is no key which is used to identify an entry) and, again, the _id ir deleted. Every insert / update generates new data entry (or row) with only one value, because the _id is deleted.

You can remove the code lines mentioned above and it will work as expected.

Hi Jaroslavas and thank you for taking the time to answer me.

[EDIT]: Ok I was able to figure the cause of the issue => the data Editor. WixData hooks probably work as expected.

If anyone has the same issue:

The data editor uses the value returned by the after hook to populate newly inserted row (after one of the fields is edited) But since the returned object is not the original item but his modified copy, it’s the copy who is displayed in the original table(Project collection here).

Thing goes back to normal if you reload the data editor and data is reloaded with the correct value.

But if you edit a second field, the Data editor actually triggers the update based on the current data (so the modified copy) therefor inserting a new object since the ID is the copyID and not the originalID.

Solution

return the original item after the hook.

export function Projects_afterInsert(item, context) {
    let copy = {
         field1: item.field1,
         field2: item.field2,
         originalId: item._id,
         ...
    }
    return wixData.insert('copy', copy, options).then(() => item);
}

export function Projects_afterUpdate(item, context) {
    let copy = {
         field1: item.field1,
         field2: item.field2,
         originalId: item._id,
         ...
    } 
    
    return wixData.query('copy').eq('originalId', copy.originalId).find().then(result => {
        copy._id = result.items[0]._id;
        return wixData.update('copy', copy, options).then(() => item);
    });
}

To answser your question :

what is the idea behind

  item.originalId = item._id;
   delete item._id;

lines?

I want to copy the whole item from one collection to another while keeping a reference to the original item.

Thank you for your time and I hope I will help someone else in the future

Hi I used this code works perfect, let me know its work for you

$w . onReady ( function () {
let itemObj
$w ( β€˜#dataset1’ ). onReady ( () => {

$w ( β€˜#button4’ ). onClick (()=>{
itemObj = $w ( β€˜#dataset1’ ). getCurrentItem ();
console . log ( itemObj )
console . log ( itemObj . title )
console . log ( itemObj . make )
console . log ( itemObj . model )

$w ( β€œ#dataset3” ). onReady (() => {
$w ( β€˜#dataset3’ ). setFieldValue ( β€˜title’ , itemObj . title )
$w ( β€˜#dataset3’ ). setFieldValue ( β€˜make’ , itemObj . make )
$w ( β€˜#dataset3’ ). setFieldValue ( β€˜model’ , itemObj . model )
$w ( β€˜#dataset3’ ). save ()

})
})

$w ( β€˜#button4’ ). onClick (()=>{ $w ( β€˜#input1’ ). value = $w ( β€˜#dataset1’ ). getCurrentItem (). title })
$w ( β€˜#button4’ ). onClick (()=>{ $w ( β€˜#input2’ ). value = $w ( β€˜#dataset1’ ). getCurrentItem (). make })
$w ( β€˜#button4’ ). onClick (()=>{ $w ( β€˜#input3’ ). value = $w ( β€˜#dataset1’ ). getCurrentItem (). model })
})

});