Two controllers rely on an HTTP request within a factory for their functionality

I am facing a situation where I have 2 controllers that rely on data fetched by a function within a factory. The structure of my factory is like this:

factory.getData = function() {
   const req = {...};
   return $http(req).then((res) => {
       this.data1 = res.data.response[0];
       this.data2 = res.data.response[1];
       return res;
})

In my controllers, I call the factory's getData function like this:

this.factory.getData().then((data) => {
    this.controllerData1 = this.factory.data1;
    this.controllerData2 = this.factory.data2;
})

Please note: I have omitted the actual name of the factory. Although this approach provides me with the necessary data, it results in both controllers triggering the HTTP request simultaneously, which is not optimal. I need to ensure that the second controller waits until data1 and data2 are defined. How can I achieve this?

Answer №1

factory.dataPromise = null;

factory.getData = function() {
   if (this.dataPromise !== null) {
      return this.dataPromise;
   }
   else {
       const req = {...};
       return this.dataPromise = $http(req).then((res) => {
           this.data1 = res.data.response[0];
           this.data2 = res.data.response[1];
           return res;
       })
   }
}

This answer may be a bit simplistic, but it should suffice for now. However, I recommend refactoring the code for better efficiency. Nevertheless, I tried to keep the changes minimal.

The crucial point is always returning a promise. By ensuring that, everything should work smoothly. If we verify that this.data1 and this.data2 already exist, we can return a resolved promise immediately without making an additional HTTP request.

Just a reminder, include $q (or any other Promise library of your choice) to create promises easily.

To Consider: It's not a major issue, but when you invoke factory.getData(), you're not actually utilizing the resolved value from the promise. Hence, in my answer, I simply have a placeholder variable called whateverdata, as the returned value based on your code is irrelevant since it's not being used.

In this scenario, it might be better to let the promise handle the task. In light of this, I propose the following refactor:

factory.dataPromise = null;

factory.getData = function() {
   if (this.dataPromise !== null) {
      return this.dataPromise;
   }
   else {
       const req = {...};
       return this.dataPromise = $http(req).then((res) => {
           this.data1 = res.data.response[0];
           this.data2 = res.data.response[1];
           return { data1: this.data1, data2: this.data2 };
       })
   }
}

this.factory.getData().then((data) => {
    this.controllerData1 = data.data1;
    this.controllerData2 = data.data2;
})

This approach is more intuitive and effectively capitalizes on the advantages of promises. Ultimately, the decision rests with you.

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

My React project is unable to locate a file after I modified its extension from .js to .tsx

After using npx create-react-app my-app to start my React project and adding Typescript, I encountered an issue after converting one of my components to a .tsx file. The error message I received was: Module not found: Error: Can't resolve './cont ...

What could be causing the undefined state of my AngularJS model?

Take a look at my code snippet: <div ng-controller="EditModalCtrl"> <form> <input type="text" placeholder="Composer name" ng-model="media.composer" value="{{ media.composer }}" /> <input type="text" placeho ...

Express server is receiving undefined post parameters from Axios in Vue, even though they are clearly defined in Vue

Within my code, I am utilizing an <img> element as shown below: <img v-bind:word = "thing" @click="action" align="center" src="../assets/pic.png"/> Alongside, there is a method structured in this manner: ...

Is there a way in which I could instruct 40 buttons to individually correspond to the table row on which they are placed, without the need for 40 distinct events, using JavaScript and PHP?

Imagine a scenario where there is a large table of products, each row containing the product name, its price, and a "Rebate?" checkbox. For every product in this table, there are two corresponding values: fullPrice and rebatePrice. If the "Rebate?" checkbo ...

JavaScript: Find options in a datalist that correspond to user input

One of the features I am working with is a text input that utilizes a datalist. The content of this datalist is populated dynamically using PHP: <input type="text" name="city" list="cities" id="city"> <datalist id="cities"> <?php ...

Can sound be triggered from a JS file within Django's HTML template without using Ajax?

I'm currently in the process of transitioning a website to utilize the Django framework. Most of the JS scripts are functioning properly, except for those that involve sound. Specifically, I have a play/pause button for a song and some sounds that sh ...

Exploring the power of for-loops in Reactjs within the componentDidMount lifecycle

I'm struggling to understand why the state of my component fails to update inside a for-loop. Let's look at an example: class Example extends React.Component { constructor() { super() this.state = { labelCounter ...

Unable to Trigger onClick Event with react-bootstrap Navbar Dropdown in Combination with react-router-dom

In my React application with react-bootstrap, I have a Navbar component that displays a dropdown menu for different brands. However, I noticed that the second brand option (Tommy Hilfiger) is always the one active by default, as if it is automatically cl ...

"Struggling with AngularJS nth-child not functioning properly within an ng-repeat loop

I've been working on changing the styling of every second row of content displayed on the page using ng-repeat. I managed to make it work for font color, however, I'm struggling with changing the background color. Below is my code. I would appre ...

What causes the picturesArray to remain consistently void?

const fetch = require("node-fetch"); let images = []; fetch('http://www.vorohome.com//images/assets/159314_887955.png') .then(response => response.buffer()) .then(buffer => { const data = "data:" + response.headers.get ...

Ways to activate JavaScript on a completely dynamic AJAX ASP.NET website

Encountering a dilemma: I have developed a fully dynamic site with only one update panel on the startpage. All content is generated dynamically through code behind, with different pages as web user controls. The issue arises when attempting to open two d ...

Obtain the initial element in a table using pure Javascript

There are two tables presented in the following format: <table> <tr> <td></td> <td></td> </tr> </table> <table> <tr> <td></td> <td>&l ...

Error: The property 'language' is undefined and cannot be read

Struggling to execute the App-test.js file provided by React Native in the __test__ directory: import 'react-native'; import React from 'react'; import App from '../src/app'; // Note: test renderer must be required after rea ...

Navigating between components in angular2 modules: A tutorial

Currently, I am utilizing angular2 Final version for my development tasks. Within my project, I have established 3 distinct modules: AppModule ProjectModule DesignerModule In the past, I solely had AppModule which integrated the following RoutingModule ...

Standardize date formatting in AngularJS

Retrieve the date in the shared format: {{ dateValue | date:{{dateFormat}} }} The following service is provided: app.service('formatting', function() { var format = new Object(); format.dateFormat = 'medium' var ...

The communication between the child and parent components is failing to function correctly

I'm trying to send data from a child component to a parent component, but the function isn't being invoked correctly. It doesn't seem to work as expected. <router-outlet (activeElement)='getActive($event)'></router-outlet ...

Unraveling the Mystery of React Event Bubbling: Locating the Desired

I am working with a <ul> Component that wraps several <li> Components. To streamline my code, I would like to avoid adding an individual onClick handler to each li and instead utilize a single handler on the parent ul element to capture the bub ...

The value in the input will not be refreshed

Hey there, I've been struggling to make this script work and I can't seem to pinpoint the issue. The goal is to use tinyMCE along with jQuery dialogue to take input from 2 fields and then output it in a specific format. Here's the code snipp ...

What is the best way to dynamically update a state that is deeply nested?

Is there a way to update the object using key: 1311 and retrieve the updated state while not knowing its exact location but only its key value? state = { iow: [ { key: 1, iow_description: "EARTH WORK", unit: null, rate: nul ...

Issue encountered when utilizing ngResource in factory: unable to choose JSON index

ngResource in a factory is functioning properly, but unfortunately, it is only able to select the index of the JSON. However, it is also possible to bind the same variable $scope.resultItems. The console log appears as follows ...