(NodeJS, SPA) Server Action being triggered twice (routing issue?)

Wappler Version : v3.5.6
Operating System : Windows 10
Server Model: NodeJS
Database Type: SQL
Hosting Type: Docker

Expected behavior

What do you think should happen?

The server connect should trigger once. (server connect triggers a server action with a database query

Actual behavior

What actually happens?

The server action is triggered twice

How to reproduce

  1. Set up a layout and content page

  2. On layout page, add queries course_id and lecture_id

  3. On lay out page, set up buttons that do an internal refresh - while giving the lecture_id as a query to the URL:

  4. On content page: set up a Server Connect which is connected to a database query. Give the query we set on the lay out page (step 2) as input parameter:

  5. Load the content page with the parameters in the URL, this will just trigger the server action and it’s query once (it’s get_lecture_video?lecture_id=7) in below video

  6. Now click on one of the buttons set up in step 3. :warning: This will now trigger the server action twice. See the video:

Extra:
7. If I now remove the input parameter in the server action


  1. It’s now loading the query once :white_check_mark::

My best guess is that I’m trying to retrieve a query from the main layout which somehow causes it to trigger twice? A routing issue?

Are you calling the server action somewhere? Something like sc1.load()?

It is indeed related to routing. The server connect detects the url change and then loads the content of the new url, at the same time the new content page is loaded for that url. When the content page is loaded it injects a new server connect and that one also loads the url.

@sid Not that I know of…

did a search:

Just on the watch.ejs page where I’m loading it as seen in the OP

@patrick Does that mean my set up is wrong? Any idea on how to improve it? Or is it a bug?

It is not really a bug, server connect component loads the new content when it detects the binded if changed, at the same time the view loads a new content page and after the content page is loaded it injects a new server connect component which is loaded.

As a workaround you could try using a server-side template for the url of server connect.

<dmx-serverconnect id="get_lecture_video_v2" url="api/Courses/get_lecture_video?lecture_id=<%=_('$_PARAM.lecture_id')%>"></dmx-serverconnect>

@patrick Really appreciate your help here, been breaking my head on this last few days.

  1. I’m not sure how server-side templates work, but I’ve replaced the server connect with the code you gave.

Result is that it’s indeed only loaded one time, so that’s good.

But…

  1. I can’t get the value from the db query now with the data picker. The db query should give me a value called lecture_vimeo_id

Here’s a screenshot of how it was before with the double triggering:

Any ideas :pleading_face: ?

I’ve drawn out a diagram to show you what my goal is.
I have a feeling that I’m making a fundamental mistake and now need some workaround to duct-tape flawed logic.

Please take a look and tell me if it’s set up correctly

Extra picture of the routes:

1 Like

Since you are using NodeJS templates, I would suggest using server-side rendering. Some documentation is here: https://docs.wappler.io/t/sever-side-rendering-with-nodejs/21650.

The Wappler UI currently only has limited support for server-side rendering, it allows you to insert server bindings in text content, title and meta tags. It is not yet possible to insert it on attributes of components.

You can edit it in code view if you are up to it, for the templates in NodeJS EJS is used (https://ejs.co/).

An other option is to remove the :lecture_id from the path and pass it as querystring parameter, you then don’t have the url but the view will not reload when the querystring changes and it will only update the serverconnect component on the page.

Thanks Patrick will try your options.

As for your last option, this would show the URL like: /watch/:course_id?lecture_id=…

Correct? Then what is the difference from doing that and using the URL rewriting (making the route with :lecture_id?

Thanks!