Automatically refresh repeater after th page has loaded if data changes

Product:
Wix Editor

I have a dataset (CMS) which controls the data in a repeater.

In my backend I have two cron jobs that run at #minutes after each hour.
One removes expired events and the other updates a status field in the events if the event is this current day.

When the page load, old event will not display in the repeater if removed already and a tag in the repeater and also one on the page will show and highlighting todays event if there is one or the tag will not show at all.

This works fine.

But if these or any changes occur to the CNS after the page has loaded, I want the repeater items and separate tag element to auto update without the user having to refresh

I know there is a .refresh() API but for the life of me I cannot seem to target or get it to work in the backend let alone on the page.

On the page I would expect to use a setintval. But cannot find a way to access the cms.

$w(“#SpecialEventsDataset”).refresh()
Does not work. mainly because $w(“#SpecialEventsDataset”) is not being recognised as a dataset?.

I also tried it in a data hook but again cannot find a way to incorporate the refresh as one, the seem to per item and also I cannot seem to target a dataset directly.

It would seem to me the data hooks would be the best place for these but I may be wrong and the page or backend code would be better.

  export function SpecialEventsDataset_afterUpdate(item, context) {
// 	dataset .refresh()  code ?
  }

  export function SpecialEventsDataset_afterUpdate_afterRemove(item, context) {
// 	dataset .refresh()  code ?
  }

Can someone tell me what I am missing here please and point me in the wrong direction.

Cheers

Hi, Mark_Hunte !!

I see. I believe you can detect collection updates using data hooks (although they may occasionally not work as expected). Therefore, by using the Wix Realtime API, you could send a message from within SpecialEventsDataset_afterUpdate, and then receive it on the page. This way, when the collection is updated, you might be able to refresh the dataset using refresh(). :wink:

Hi, thats what I am trying to do but do not have nor can get the correct refresh syntax

In backend, data hook detects collection updates → In backend, Wix Real-Time API sends a message to the frontend → In frontend, within the Wix Real-Time message reception event, the dataset could be updated using .refresh(). I think this could work! Although I’ve never tried it before! :smiley:

How about creating the dataset again ? :thinking:

Thanks, I did think I had been clear,
I can create the hooks no problem.

But I need code that will access the dataset as an whole and refresh it.

Thats the bit I am struggling to find the correct syntax and api.

I do not need to recreate the dataset???

Just to confirm, in which file is this code located? Also, is the name of the collection actually “SpecialEventsDataset”? :thinking: Also, “_afterUpdate_afterRemove”—did you write that yourself, by any chance?

When you add a data hook to a collection, a function should automatically be written in the backend data.js file. Therefore, it seems unlikely that a non-existent data hook function like _afterUpdate_afterRemove would be generated. :thinking:

  export function SpecialEventsDataset_afterUpdate(item, context) {
// 	dataset .refresh()  code ?
  }

  export function SpecialEventsDataset_afterUpdate_afterRemove(item, context) {
// 	dataset .refresh()  code ?
  }

All the hooks are generated by wix when you make a selection. and do so going through the cms datasets contextual menu in the code editor.

Sorry for the confusion : that was just a copy and paste in that post error. Not what was generated.

But we seem to be getting stuck on the creation of the hooks,
I know how to create them and they work and are correctly generated.


Honestly I appreciate you trying to help but I really would just like answers on the refresh() code itself from someone who knows how to construct them to work in my need and if possible how to use in the hooks or page code.

Ok, I’ll leave the rest to other community members. But I believe there’s probably no way to directly refresh a dataset, which is a frontend element, from the backend. :thinking: I apologize for not being able to meet your expectations !! :smiling_face_with_tear:

Sorry if my frustration came across with this. I myself help out on another forum and in doing so I learn by helping.

I am not used to asking for help in coding or learning to use a tool as I am pretty good at finding solutions myself because of this.

I think this is the most questions a have ever asked about how a product works, on a forum in such a short period of time ever.

Wix seem at a glance great and gives access to a lot but when I dive a bit deeper I am constantly coming up against inconsistent behaviours or functionality between elements or the just fall short of a logical step in design.

In many cases its like multiple team worked on elements in the same grouping but did not talk to each other, simple example is the 3d carousel for example. No control over any of it, apart from delay on rotation, auto play or on clicked. Nothing else, no control on image size or image item fit, borders, spacing etc like you have on other galleries and so this produces a hot mess if your images are all of different sizes and shapes.


Anyway, I do really appreciate you trying to help and thank you for that.

I think you are right about the backend not being the place.

So the goal would be find how to make the repeater refresh when changes happen. I would have thought this would be a built in mechanism.

1 Like

I also have mixed feelings of frustration and expectations towards Wix, haha. They tend to rush things sometimes. But since it’s a service that has shown me the fun of web development, I’d be happier if they continued for a long time. That’s why I try to answer questions when I can, in the hopes of gaining more Wix fans :wink:

1 Like

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

Pratham!! :raised_hands: you must have found it tough to provide such a long explanation all by yourself… :smiling_face_with_tear:(great effort!!) Personally, I thought this was the only way, but as a native Japanese speaker, even with a translation app, it was quite difficult for me to convey such detailed and lengthy explanations in English… Thank you! :wink:

2 Likes

Thank you so much @Pratham ,

@onemoretime , sorry I did not get this was what you were trying to point me to.

This is know very clear to me what’s going on. great explanation and thank you for the detailed guide and coding.

Very much like a postMessage system ( bit more complex ).

I have followed the steps through and it even made me realise why when I tried to set up Refresh() before my dataset was not being recognised as such. I was using the cms id instead of the dataset id in the dataset setting. Doh. Totally forgot they are different.

But what I am getting is this error.

[Log] Realtime Connection Error – {errorCode: 2, message: "subscribe failed", channel: {name: "itemUpdated"}} (feature-telemetry-wix-code-sdk.05346426.chunk.min.js, line 1)

Can’t see why, I did think it may be an order of execution on the page load so I moved the call below my other on.ready functions but no change.

1 Like

I’m glad it finally got through! :wink: Yes, it’s the same as how postMessage() acts as a bridge between iframes and pages. It’s useful for passing messages from the backend to the frontend when needed! However, sometimes the connection can drop, causing it to not work… :melting_face:

And it just connected. Hopefully it continues to work. Pretty fast as well.

Again thanks both.

2 Likes

Always a pleasure to give back to the community I’ve learnt so much from (:

Glad it works now.

Yes sometimes Wix Realtime fails to connect to the particular channel. In this case, you can try calling the connectToRealtime() function inside the error handler maybe in every five seconds or so.

 .catch((err) => {
            console.log("Realtime Connection Error", err);
            setInterval(() => {
                connectToRealtime();
            }, 5000);
        });

@onemoretime , @Pratham

Just a quick questions. I had a couple of cron jobs running that also updated the cms to remove old events and also set a status on TODAYS event.

This was working but just noticed since about the same time I have been messing around with the hooks, it looks like they have stopped working. Can’t see them firing and the link function don’t to give out any console logging that I put in.

Not sure if it’s related, probably not.??.

The timing couldn’t get any worse :smiling_face_with_tear:

There seems to be an issue with cron jobs on Wix’s end, and multiple users have reported that their cron jobs have stopped working. Nothing we can do from our end. All we can do is wait for the Wix team to fix it asap.

1 Like

Lol, thanks for confirming that was just starting to drive me nuts.
Looks like mine stopped about the 4th, as an event that should have been removed for the day before and subsequent stale days are still there.

I send an email to myself every day via a cron job to check if everything’s working, and I did receive it this morning (about 11 hours ago). :thinking: I guess it might vary depending on the region.

1 Like