The data isn't updated in repeater after saving a new item in collection

Hello, I faced with problem with updating data in repeater. When user adds new item using the form, the new record is not displayed in repeater. If to reload the page, the record is updated:

After pressing button “Send”, the function loadMaterialButton_click starts working:

export async function loadMaterialButton_click(event) {
 let loadResult = $w('#loadMaterialResult');
 
 if($w("#uploadFileButton").value.length > 0)
 {
        $w("#uploadFileButton").startUpload()
                .then( (uploadedFile) => {
                let toInsert = {
                               "title":          $w('#subjectInputField').value,
                               "mainCategory":   $w('#mainCategoryMaterialsInProfile').value,
                               "subCategory":    $w('#subCategoryMaterialsInProfile').value,
                               "documentUrl":    uploadedFile.url
 };
                insertToDb("document_db", toInsert); //document_db is collection where the new item is saved
                loadResult.text = "Upload successful";
                loadResult.show();
                resetLoadMaterialFields();
 })
 .catch( (uploadError) => {
                resetLoadMaterialFields();
                loadResult.text = "File upload error";
                loadResult.show();
                console.log("File upload error: " + uploadError.errorCode);
                console.log(uploadError.errorDescription);
 });
 }
}

The function insertToDb saves the new item to collection and refresh dataset (dataset is connected to document_db is collection):

async function insertToDb(db, itemToInsert)
{
    wixData.save(db, itemToInsert);
    $w("#documentDbInProfile").onAfterSave( () => {
        $w("#documentDbInProfile").refresh(); 
        let page = $w("#paginationForUserMaterials").currentPage;
        let skipCount = (page - 1) * 10;
        getMaterialsByCurrentUserId(skipCount, 10);
 })
}

The function getMaterialsByCurrentUserId sends request with query and update repeater:

async function getMaterialsByCurrentUserId(skipNumber, numberLimit){
 let query = wixData.query("document_db")
 .eq("_owner", wixUsers .currentUser. id) //here I set currentUser. id
 .skip(skipNumber)
 .limit(numberLimit)
 .descending("_createdDate");

 let res = await query
 .find()
 .then((result) => {
            $w('#repeaterUserMaterials').data = result.items;

            $w('#repeaterUserMaterials').onItemReady(($item, itemData, index) => {
                $item("#titleText").text = itemData.title;
                $item("#mainCategoryText").text = itemData.mainCategory;
                $item("#subCategoryText").text = itemData.subCategory;
 })
 });
}

Could you help me to solve this issue. Thanks in advance.

I think this should be in the $w.onReady()-code-part.

$w('#repeaterUserMaterials').onItemReady(($item, itemData, index)=>{                 
   $item("#titleText").text = itemData.title;                 
   $item("#mainCategoryText").text = itemData.mainCategory;                 
   $item("#subCategoryText").text = itemData.subCategory;
});

$w.onReady(()=>{

});
                              • your code part + + + + + + + + + + + + + +
$w('#repeaterUserMaterials').onItemReady(($item, itemData, index)=>{                 
   $item("#titleText").text = itemData.title;                 
   $item("#mainCategoryText").text = itemData.mainCategory;                 
   $item("#subCategoryText").text = itemData.subCategory;
});

= = = = = = = = = = = = = = = = RESULT = = = = = = = = = = = = = = = = = =

$w.onReady(()=>{
    $w('#repeaterUserMaterials').onItemReady(($item, itemData, index)=>{                 
        $item("#titleText").text = itemData.title;                 
        $item("#mainCategoryText").text = itemData.mainCategory;                 
        $item("#subCategoryText").text = itemData.subCategory;
    });
});

A REFRESH of DATASET won’t help here, because you populate your REPEATER by CODE and you surely have no CONNECTION between REPEATER and DATASET in the Wix-Property-Panel, don’t you?

A mixing usage of both ways, would cause inteferances (on my opinion).

Either you do everything by code, or you do (almost) everything by a connection in the wix-editor’s property-panel.

But, i think you should go the CODING-way (more flexible).


The same issue here…

The -onAfterSave()-Function should be a stand-alone-function and should not be placed inside another function.

$w("#documentDbInProfile").onAfterSave( () => {
        $w("#documentDbInProfile").refresh(); 
        let page = $w("#paginationForUserMaterials").currentPage;
        let skipCount = (page - 1) * 10;
        getMaterialsByCurrentUserId(skipCount, 10);
 })

And another question is: Does onAfter-Save ever do some action?
I am not sure if onAfterSave is running after —>

wixData.save(db, itemToInsert);

Normaly you should use —>

… or …

… to fire up the onAfter-Save-function ( on my opinion).

And now you have reached the point where it starts to be complicated (because of MIXING —> Wix-Data & DATASET -functions).

How to solve your problem.

  1. You can use a DATASET, but i would disconnect it completely and would connect it just with the related DB. All the rest will be done by code.
  2. Populating REPEATER —> by CODE.
  3. Using DATASET to fire up onAfterSave().

This will surely have the one or the other bug, because i did it just the theoretical way and did not test it. You will have to debug it a little bit by your own.

import wixData from 'wix-data';
import wixUsers from 'wix-users';

var DATABASE = "document_db";
var DATASET = "documentDbInProfile"
var DATAFIELD = "_owner";
var LIMIT = 1000;               //<---Modify by your own
var SKIP = 100;                 //<---Modify by your own

$w.onReady(()=>{
  $w("#"+DATASET).onReady(()=>{  
     //-------------------------------------------------------------------
      $w('#loadMaterialButton').onClick(()=>{
         let loadResult = $w('#loadMaterialResult');
 
         if($w("#uploadFileButton").value.length>0){
            $w("#uploadFileButton").startUpload()
            .then((uploadedFile) => {
               loadResult.text = "Upload successful";
               loadResult.show();
               resetLoadMaterialFields();
 
               $w("#"+DATASET).setFieldValues({
                  "title":          $w('#subjectInputField').value,
                  "mainCategory":   $w('#mainCategoryMaterialsInProfile').value,
                  "subCategory":    $w('#subCategoryMaterialsInProfile').value,
                  "documentUrl":    uploadedFile.url
               });
                $w("#"+DATASET).save();
            })
            .catch( (uploadError) => {
                resetLoadMaterialFields();
                loadResult.text = "File upload error";
                loadResult.show();
                console.log("File upload error: " + uploadError.errorCode);
                console.log(uploadError.errorDescription);
            });
        }
     });
       
    //-------------------------------------------------------------------
    $w("#documentDbInProfile").onAfterSave(() => {
        $w("#documentDbInProfile").refresh(); 
        let page = $w("#paginationForUserMaterials").currentPage;
        let skipCount = (page - 1) * 10;
        getMaterialsByCurrentUserId(skipCount, 10);
    });
    
    //-------------------------------------------------------------------
    $w('#repeaterUserMaterials').onItemReady(($item, itemData, index)=>{                 
        $item("#titleText").text = itemData.title;                 
        $item("#mainCategoryText").text = itemData.mainCategory;                 
        $item("#subCategoryText").text = itemData.subCategory;
    });
  });
});


// The only function where i would use Wix-Data...(this is ok).
async function getMaterialsByCurrentUserId(skipNumber, numberLimit){
    let VALUE = await wixUsers.currentUser.id
    wixData.query(DATABASE)
   .eq(DATAFIELD, VALUE)
   .skip(SKIP)
   .limit(LIMIT)
   .descending("_createdDate")
   .find()
   .then((result)=>{console.log("Here --> populating REPEATER with RESULT-DATA")
       $w('#repeaterUserMaterials').data = result.items;
   });
}

Or you go the Wix-Data-way, and do not use DATASET.

Thanks a lot for advice.

A REFRESH of DATASET won’t help here, because you populate your REPEATER by CODE and you surely have no CONNECTION between REPEATER and DATASET in the Wix-Property-Panel, don’t you?

I have connection between REPEATER and DATASET:

And another question is: Does onAfter-Save ever do some action?

I’ve re-checked, you were right.

Or you go the Wix-Data-way, and do not use DATASET.

Do you have an example how to connect the REPEATER and Wix-Data?

@evgarmashpro

Take this one as example…

import wixData from 'wix-data';
$w.onReady(function () {
  $w("#myRepeater").onItemReady(($item, itemData, index) => {
    $item("#myText").text = itemData.text;
    $item("#myImage").src = itemData.image;
 // Link to the dynamic item page
    $item("#myButton").link = itemData.url; 
 });
});
export function searchButton_click(event) {
 let searchResult = $w('#searchInput').value;
  wixData.query("MyCollection")
 .eq("searchField", searchResult)
 .find()
 .then((results) => {
 if (results.totalCount > 0) {
          $w("#myRepeater").data = results.items;
 } else {
          $w('#noResultsMsg').show();
 }
 })
 .catch((err) => {
 let errorMsg = err;
 });
}

Thanks a lot for helping. I’ve chosen the CODING-way (more flexible) and got rid of using DATASETs . And also I was able to solve issue with delaying. The problem was that data took certain time to insert and repeater used to update before loading data in collection. As result, I use function .then() where I update the repeater:
await wixData . insert ( db , itemToInsert ). then (( results ) => {
//here I update the repeater
});

молодец! Well done! The most effective learning method → learning by doing & solving by doing yourself :wink:

Don’t forget to like it if you really liked it.:grin: