Single 'state.executing' Statement for ANY Server Connect?

I’ve been using my app on a train, and finding it frustrating as my mobile signal comes and goes… sometimes server connects either take seconds to execute or give an error state, and I’m wondering about the best way to handle this situation for my users.

One thing I’d like to do is have a single universal spinner which is shown when any server connect is running.

So for a single server connect I can have a statement like:

get_payment.state.executing

However my app has about 200 server connects, so that would make for a very big OR statement.

So I was wondering…

Is there a statement which is true if ANY server connect is executing?

So something like:

any_server_connect.state.executing

If not, then any other ideas about how to do this would be really appreciated!

Best wishes,
Antony.

hi @Antony,

I don’t think there will be a way other than checking your connection with flow before each query. I couldn’t think of any different ideas. Maybe someone can offer different suggestions.

1 Like

I asked for a set of dynamic events for all SC/form actions here which could help:

Looking at properties such as executing would be good too, but may be very difficult. You could maintain an array of running SCs with some Javascript. I’ll have a look. Potentially you could do a find/replace on your pages to add it to all sever connect components really easily.

1 Like

So I have tested it out like this…

<dmx-value id="sc_executing" dmx-bind:value="
    bookings_activity.state.executing ||
    attendees_activity.state.executing ||
    responses_activity.state.executing
    "></dmx-value>

… and my spinner shows on sc_executing.value.

All works well so far.

@teodor, can you tell me if I am likely to get performance issues if I make this OR statement have 200 elements?

It’s a lot of typing if I’m wasting my time doing it this way!

Thanks,
Antony.

Having 200 server actions on a single page is probably not the best thing to do :slight_smile: I doubt you need 200 server actions loading at the same time on the page?

Yes, but I want one spinner to show if any of the 200 server actions are executing…

Maybe I’ll make 4 spinners and each can have a 50 element OR statement…

Will report back on how it works! :slight_smile:

Oh, and yes, I do have 200 server actions on one page… works absolutely fine!

I also don’t think using such extremely huge and long expressions with 50-200 checks inside is a nice idea.

A workaround:
Create a variable - varIsSCRunning
Set condition on spinner as varIsSCRunning.value
In each of your 200 SC, set on start dynamic event to set varIsSCRunning.setValue(true), and on done dynamic event varIsSCRunning.setValue(false).
Only downside of this is if you are running more than 1 SC in parallel, loader will stop showing as soon as the first one completes.

P.S. 200 SC on a single page is just bad code. :man_shrugging:

Instead of boolean, use an integer:

Instead of setting true, you increment by 1
Instead of setting false, you decrement by 1

This way you can have multiple SC in parallel without causing issues with the loading spinner

This could probably be integrated directly within Wappler’s framework though

3 Likes

Hey everyone, thank you sooo much for all your ideas! :pray:

I actually only have 164 Server Connects, but I was in the right ball park and need to add the executing state of all my forms too, so will be around 200 in total.

I’ve just tried the “variable with 164 OR statements” idea. After a few minutes of using the app, it put my computer’s resource from using from a normal 4% CPU / 170Mb RAM up to 20% CPU / 230Mb RAM. The fan kicked in and it started to sound painful.

@patrick - I’m still using 3.9.7 - do you think a “variable with 164 OR statements” would be much more optimised now you have the optimised App Connect in place?

@sid and @Apple, I’m loving your combined idea, I’ll give that one a go.

Best wishes,
Antony.

I hear where you are coming from @sid

My entire app is a single “page”, with lots of php includes. It runs like a dream, I have the code really well organised, and the functionality requires that many SC… So all is good, I’m super happy with it all!

You could put them all into individual Library calls, have one server connect call them all in parallel, setting a flag at start and end as appropriate. Probably a little faster as less network overhead, less concurrent threading and certainly more manageable within one SC, and cleaner.

Hi @Antony,
you could try the following:

Add this javascript into your page or from a referenced JS file

let scrun = 0;
function startsc(e) {
    let cv = dmx.global.get('runningsc');
    if (!cv) { cv = []; }
    cv.push(e);
    dmx.global.set('runningsc', cv);
}

function checkrunningsc() {
    return new Promise(function (resolve, reject) {
        let cv = dmx.global.get('runningsc');
        let ov = cv;
        for (let i in cv) {
            if (!cv[i].data.state.executing) { cv.splice(i, 1); }
        }
        if (cv != ov) {
            dmx.global.set('runningsc', cv);
            return resolve(cv);
        } else { return resolve(cv); }
    })
}

setInterval(function () {
    checkrunningsc().then(function (r) {
        if (r.length) { if (scrun === 0) { scrun = 1; dmx.requestUpdate(); } }
        else { if (scrun === 1) { scrun = 0; dmx.requestUpdate(); } }
    });
}, 200)

Then if you do a find/replace for
<dmx-serverconnect
and replace with
<dmx-serverconnect onstart="startsc(this)"

On your page, you can the hide/show elements using

dmx.show="runningsc.hasItems()"

I’m sure there’s a more elegant solution to this but it works OK in my testing without too much overhead.

Essentially it maintains an array of Server Connect items (added to the array on start) every 200ms (adjust if you want at the end of the setInterval) it checks through the array to see if they are still running, removing any that aren’t. Finally it checks for items and when it changes from/to no items left, it requests an update of dmx components (to get the page elements to see there has been a change)

With this dynamic SCs (inside repeats) should still be managed and you should also be able to add the onstart bit to SC forms too.

1 Like

Do you want to know if any of the SC is running at any time or just the ones on page load?

Most simple way when you want to know if there is any SC running is using the events start and done.

<dmx-value id="is_loading" dmx-bind:value="0"></dmx-value>

<dmx-serverconnect id="sc1" url="api/action"
  dmx-on:start="is_loading.setValue(is_running.value + 1)"
  dmx-on:done="is_loading.setValue(is_running.value - 1)"
><dmx-serverconnect>

<div dmx-show="is_loading.value">Loading</div>

The preloader component will wait for all serverconnect that started loading on page load, here the part of the preloader script that gets all serverconnect instances (it doesn’t check executing but it checks if data is set).

checkDataLoaded: function() {
  this.dataLoaded = this.getDatasets().every(function(data) { return data.data != null });
},

getDatasets: function() {
  var datasets = [];

  dmx.app.children.forEach(function _getDatasets(child) {
    if (child.data.$type == 'serverconnect' && !child.props.noload) {
      datasets.push(child.data);
    }

    child.children.forEach(_getDatasets);
  });

  return datasets;
}
2 Likes

Hey everyone, thank you sooo much for all your ideas… the Wappler Community Rocks! :rocket:

I’ve done the is_running +1 version as proposed by @patrick and @Apple, and it seems to be working really well.