'Global variable is undefined if assign variable in the TargetConnected method in stimulus.js

This is the location controller file that is going to access by the html code.

export default class extends Controller {
    static targets = [ "visible", "map" ]

    mapTargetConnected(element) {
      this.name = "aaa"
    }

    add(event) {
      console.log(this.name) // this line is logged that variable is undefined.
    }
}

here is the HTML code

<%= form_with(model: @location, local: false, url: location_path(), data: {controller: 'location', action: 'ajax:beforeSend->location#add'}) do |form| %>
....
<% end %>

This is the code regarding form submit via ajax request. if i access the this.name variable inside the add method or click event its says the variable is undefined… but if i same name variable assign it in connect() method than it’s working…

but i want to assign variable at targetConnected method and use it in the add action method.Please suggest any solution or let me know if i'm doing wrong.



Solution 1:[1]

Most likely the add event is being triggered before the mapTargetConnected has run.

Stimulus will go through the DOM and match elements and their targets and then trigger the relevant someTargetConnected and connect lifecycle methods once the controller is set up.

However, this is not instant and there may be some nuance to how the timing works when you are working with other events.

You will need to work out when the actual map target is being added to the DOM and possibly do some logging to check that timing compared to when the ajax:beforeSend event triggers.

Sometimes, adding a setTimeout can assist as it will ensure that the code provided to it runs 'last' (there is some nuance to this, technically it is the next event cycle).

For example

    add(event) {
      // here the mapTargetConnected may not have run
      setTimeout(() => {
        // by this point, mapTargetConnected has hopefully now run
        console.log(this.name);
     });
    }

It is hard to offer more help without a bit more specifics on what ajax:beforeSend is and when it triggers, along with what actually adds the map target to the DOM. It may be more helpful to write this question with the initially rendered HTML output (with the minimum parts to help guide the question).

In general, it is good to remember that in the browser, things do not happen instantly, while they may be fast there can be timing issues to be aware of.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 LB Ben Johnston