Ways to ensure emit functionality works seamlessly in a synchronous fashion

I've been attempting to show a spinner while the page is loading using angular $emit along with a command file. Below is my model:

Model:

    model.load = function(){
        model.loading = true;
        $rootScope.$emit('loadMyPage', model.loading);
        return service.getData().then(storesResult, storesFault);
    }


       var storesResult = function (value) {
        model.categoriesLoading = false;
        $rootScope.$emit('loadMyPage', model.loading);
        model.stores = value.result;
        saveData();
    };

    var storesFault = function (value) {
        var data = value.data;
        var status = value.status;
        model.categoriesLoading = false;
        model.stores = null;
        $rootScope.$emit('loadMyPage', model.loading);
        $rootScope.$emit('systemAlert', {title: 'Loading Error', message: data, status: status, type: 'danger', timeout: 10000, showAsModal: true});
        return value;
    };

The Command file that runs in app.run is as follows:

command.execute = function () {
            $rootScope.$on('loadMyPage', onLoadingChange);
        };

        var onLoadingChange = function (event, value) {
            if (model.loading === true) {
                showModal('sections/modals/loading/loading.tpl.html');
            } else {
                hideModal();
            }
        };
};

The issue arises during page load where the $emit from model.load doesn't reach $on in command. Instead, it's being triggered by the storesResult block. Consequently, model.loading always ends up as false, possibly due to an asynchronous problem.

Please feel free to provide any suggestions.

Answer №1

Consider avoiding the use of $emit and $on. If you have access to the $rootscope object, simply create a key-value pair or store the data you need for checking. You can wait for the data using $watch, or implement a callback with $rootscope.

Model:

    model.load = function(){
      // model.loading = true;
      $rootScope.isLoading = true;
      return service.getData().then(storesResult, storesFault);
    }


    var storesResult = function (value) {
      model.categoriesLoading = false;
      $rootScope.isLoading = true;
      model.stores = value.result;
      saveData();
    };

    var storesFault = function (value) {
      var data = value.data;
      var status = value.status;
      model.categoriesLoading = false;
      model.stores = null;
      $rootScope.isLoading = true;
      $rootScope.$emit('systemAlert', {title: 'Loading Error', message: data, status: status, type: 'danger', timeout: 10000, showAsModal: true});
    return value;
};

command.execute = function () {
        $rootScope.$watch('isLoading', onLoadingChange);
    };

    var onLoadingChange = function ( value ){
        if (value === true) {
        // or simply if( value )
            showModal('sections/modals/loading/loading.tpl.html');
        } else {
            hideModal();
        }
    };
};

HOWEVER

Using $rootScope to store attributes may not be the optimal solution. Consider other approaches.

ALSO

A brief explanation on $emit and $broadcast:

Controllers are instantiated with $scope DI'd => link (they are not singletons);

Here's how broadcast and emit work in a nested scenario:

                   3
               --------
              |        |
             ---     ----
            1   |    2   |
          ---  ---  --- ---
          |  | |  | | | | |

Refer to this tree structure when considering the following communication questions using broadcast and emit.

  1. How does node 1 communicate with node 3?

In one.js file:

scope.$emit('messageOne', someValue(s));

In three.js file:

scope.$on('messageOne', someValue(s));
  1. How does node 2 communicate with node 3?

In two.js file:

scope.$emit('messageTwo', someValue(s));

In three.js file:

scope.$on('messageTwo', someValue(s));
  1. How does node 3 communicate with node 1 and/or 2?

In three.js file:

scope.$broadcast('messageThree', someValue(s));

In one.js && two.js files based on your chosen recipient.

scope.$on('messageThree', someValue(s));
  1. How does node 2 communicate with node 1?

In two.js file:

scope.$emit('messageTwo', someValue(s));

In three.js file:

scope.$on('messageTwo', function( event, data ){
  scope.$broadcast( 'messageTwo', data );
});

In one.js file:

scope.$on('messageTwo', someValue(s));

HOWEVER

When dealing with multiple nested nodes that need to communicate, the usage of $emit, $broadcast, and $on can become complex. One approach is to centralize the messaging system within the parent node.

In the PARENT NODE (in this case, node three)

In three.js:

scope.$on('pushChangesToAllNodes', function( event, message ){
  scope.$broadcast( message.name, message.data );
});

Now, any child node only needs to $emit the message or listen for it using $on.

NOTE: While $emit, $broadcast, and $on are useful for specific scenarios, ensure there isn't unnecessary cross-communication within nested paths.

  1. How does node 2 communicate with node 1?

In two.js file:

scope.$emit('pushChangesToAllNodes', sendNewChanges());

function sendNewChanges(){
  return { name: 'talkToOne', data: [1,2,3] };
}

In three.js file:

This scenario has already been addressed.

In one.js file:

scope.$on('talkToOne', function( event, arrayOfNumbers ){
  arrayOfNumbers.forEach(function(number){
    console.log(number);
  });
});

While specific listeners are still needed, this centralized approach simplifies communication across nodes without direct parent involvement.

I hope this explanation is helpful...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for hiding the calendar icon once a form has been submitted

Below is the HTML code snippet for the date field. <asp:TextBox ID="txtExpiryDate" runat="server" Width="80px" MaxLength="10" CssClass="fromDate" /> And here is the HTML code snippet for the Submit button. <asp:Button ID="cmdSubmit" runat=" ...

Utilizing Rails for dynamic form validation with AJAX

As someone who is new to jQuery, AJAX, and JavaScript in general, I am facing a challenge with front-end validation for a Rails form that utilizes an ajax call to query the server. The validation works fine when I am debugging, giving enough time for the A ...

What is a creative way to get rid of old content on a webpage using jQuery without relying on the

As I work on my crossword project, I have almost completed it, but encountering a problem. Within my HTML code, I have a select list that loads a .JSON file using Javascript. <form method="post" id="formulaire"> <div class="toto"> <sel ...

Using local storage with github sites can lead to some unexpected and peculiar behavior

Currently, I am working on a simple clicker game using HTML and JavaScript. To store the variables money and taxCollecters, I have implemented local storage. However, I am encountering strange issues when trying to use the save and load buttons on the Gi ...

How can I remove markers from google maps?

I have been working on a program that dynamically loads JSON data onto a map as markers when the user pans and zooms. However, I am facing an issue where I need to clear the existing markers each time the user interacts with the map in order to load new on ...

Blue Jay Guarantees: Construct props object on the fly and execute simultaneously

If we take a look at this example: https://github.com/petkaantonov/bluebird/blob/master/API.md#props---promise Promise.props({ pictures: getPictures(), comments: getComments(), tweets: getTweets() }).then(function(result) { console.log(re ...

The state of my React components keeps disappearing

Within my code, I have implemented a click event on the InterestBox to trigger updates in its appearance and alter the state of its parent container. However, despite inspecting the element using React Developer Tools and attempting API requests, the stat ...

Exploring the Power of Multiple FindOne Queries in MongoDB

I have been working on expanding the data fields returned by our API. Currently, the API retrieves student information using the find method, and also includes some project details by retrieving the student info and using findOne to obtain information abou ...

Difficulty in Verifying ECDSA Signatures Across React and Python Environments

Currently, I am tackling a project that requires me to create an ECDSA signature in a React application and then validate it in a Python backend. Although the signature generation and validation processes work perfectly within their respective environments ...

Tips for assigning a unique button and checkbox to each item in an ng-repeat list

I am currently working on a ToDo-List exercise in JavaScript and have chosen to utilize AngularJS in order to enhance my skills. Check out the Github repository here In my initial attempt, I have set up two unordered lists - one for active items and anot ...

Is there a way to showcase a block of Python code using a combination of HTML, CSS, and Javascript to enhance its

On my website, I want to display code blocks similar to how StackOverflow does it. The code block should be properly colored, formatted, and spaced out for better readability. All the code blocks on my site will be in python. def func(A): result = 0 ...

Blur-triggered form validation

Within my webpage, I'm facing an issue with 5 input fields that need to be validated on blur. Instead of relying on alert boxes, I aim to display either an error or success message through DOM scripting. Despite trying various codes, nothing seems to ...

Using a static value in the comparator is necessary for Array.find to function properly in Typescript

Looking to retrieve an item from an array: const device = this.selectedDevtype.devices.find(item => console.log(this.deviceID); return item.device_id === this.deviceID; }); console.log(device); When this.deviceID is logged, it shows "4", but t ...

Encountering a file size of 0 after updating the input file value during testing on CentOS operating system

I am encountering an issue while attempting to upload a file during my testing. I am using Protractor for testing, and although I can successfully use sendKeys to input the file and retrieve the filename and lastModified attributes, the file size is showin ...

Accessing variables from an external script in jsdom

Here is a simple example of jsdom code using the script parameter. Despite my best efforts to reference external JS files, I keep running into this issue: ReferenceError: exVar is not defined Does anyone know what might be causing this problem and how ...

Using the Promise function with callback to map the JSON payload object into an object

I received a JSON payload with the following structure: { "name": "Reports", "subject": "Monthly Reports", "attachments":[ { "attachment":{ "name": "Month1.pdf", "type": "application/pdf", "path": "h ...

Clicking on a button in HTML to open a JavaScript file

As a beginner in HTML and JavaScript, I am looking for a way to open a JavaScript file when the onclick event of a button in my HTML file is triggered. Can anyone provide me with guidance on how to achieve this? Thank you in advance. ...

Switch between two distinct menus (Reactjs + Material UI)

Recently, I designed a robust menu system that includes a Switcher feature. The concept is straightforward - if the switch is turned off, display the 1st menu; and if it's on, show the second menu. However, there seems to be an issue. When the switch ...

Processing file to retrieve information (JavaScript)

As someone who is new to the world of JavaScript and website development, please forgive me if this question seems a bit basic. The concept is to have a popup message appear on every page with some information. The issue arises when wanting to change this ...

What is the best way to retrieve an object from every function?

I'm dealing with a <div> containing radio buttons: <div id='RB-01'> <span>Item_1</span><input type='radio' name='RB01' value='1'><br /> <span>Item_2</span><inp ...