Automatically refresh repeater after th page has loaded if data changes

Hey Mark,

The approach suggested by @onemoretime, using Wix Realtime is indeed the best way to make this work.

However it is a complicated setup and I’m going to list down the steps in complete detail. If you follow each step very carefully, you’ll be able to make this work.

But first let me give you an overview of what backend and frontend is, and how Wix Realtime can bridge the gap. This may help other people in the future.

When you want to connect a page element, like a repeater or a table to a CMS database, you will see that a new dataset gets added to the page. This is a page element, which acts like a bridge between your repeater / table and the CMS by fetching and feeding the data to and fro. It fetches all the data from the CMS database it is linked to, by matching the criteria / filters (if any), and it’s job is done. Once the data is fetched from the database and delivered to the frontend, it does not continuously check if the data in the database has changed or has been updated, which is why it does not have any such event handlers.

However the database itself has something called data hooks which does just that, and that runs on the backend servers which are separate from the frontend. dataset.refresh() is a frontend function and hence cannot be called directly from the backend whenever a data hook is fired.

Which is why

the above code won’t run.

The benefit of data hooks in the backend is that they get fired every time you make a change to the database, even from the CMS in the site dashboard. Now all you need to do is tell the dataset in the frontend to refresh whenever a hook is fired. This is where Wix Realtime comes in. Consider it as a live communication system that you can use for a vast number of applications.

Lets take a user group chat for example. When one user posts a message, all users connected to the specific group (or channel) receive it. Now that you have this power, you can also use it to show maybe a notification or a popup, or ring a little notification bell…

This was just one example. You can use this same approach to communicate between your site’s backend and frontend as well. Something like:

IN BACKEND: When hook fired > Post a message on realtime that says “Fired”

IN FRONTEND: When a new message is received, perform an action

This is exactly what we are going to do here. So follow the steps below:

  1. In the backend, create a new .js file called realtime-permissions.js and copy paste this code inside it:
import { permissionsRouter } from 'wix-realtime-backend';

permissionsRouter.default((channel, subscriber) => {
    return { "read": true };
});
  1. Now create a new .jsw file called realtime.jsw and copy paste this code inside it:
import wixRealtimeBackend from 'wix-realtime-backend';

export function databaseUpdated(item) {

    let channel = {
        "name": "itemUpdated"
    }

    let message = {
        updated: true
    }

    wixRealtimeBackend.publish(channel, message)
}
  1. Now go to your data.js file that contains all the data hooks and import the above function at the beginning of your code. Then call the function in each data hook. Your code should look something like this:
import { databaseUpdated } from 'backend/realtime';

export function SpecialEvents_afterInsert(item, context) {
    databaseUpdated(item);
}

export function SpecialEvents_afterUpdate(item, context) {
    databaseUpdated(item);
}

export function SpecialEvents_afterRemove(item, context) {
    databaseUpdated(item);
}
  1. Now go to the page on the site that has the repeater and copy paste the code below:
import wixRealtimeFrontend from 'wix-realtime-frontend';

const channel = {
    "name": "itemUpdated"
};

wixRealtimeFrontend.onDisconnected(() => {
    console.log("Reconnecting to channel...");
    connectToRealtime();
})

$w.onReady(function () {
    connectToRealtime();
});

async function connectToRealtime(params) {
    console.log("Connecting to channel...");
    wixRealtimeFrontend.subscribe(channel, (message, channel) => {
            if (message.payload) {
                if (message.payload.updated == true) {
                    $w("#myDataset").refresh();
                }
            }
        })
        .then((id) => {
            console.log("Connected");
        })
        .catch((err) => {
            console.log("Realtime Connection Error", err);
        });
}

And voila! Now all you need to do is change the ID of myDataset to the actual ID of your dataset, which you can find under Dataset Settings.

And that’s pretty much it! :wink:

2 Likes