Leveraging Promises in AngularJS to create a chain between two separate controllers

I've developed a provider called MyRestServices to handle my REST-Services:

app.provider('MyRestServices', function() {
  this.baseUrl = null;
  this.setBaseUrl = function(_baseUrl) {
    this.baseUrl = _baseUrl;
  };

  this.$get = ['$http', function($http) {
    var _baseUrl = this.baseUrl;

    function getMyData() {
      return $http.get(_baseUrl + 'data1/?token=' + token + '&key=' + key);
    }

    function preGetTokenAndKey() {
      return $http.get(_baseUrl + 'keyAndToken/');
    }

    return {
      getMyData: getMyData,
      preGetTokenAndKey: preGetTokenAndKey
    };
  }];
});

Prior to making any REST service calls, I set up the configuration.

app.config(function(MyRestServicesProvider) {
  MyRestServicesProvider.setBaseUrl('https://www.test.com/rest/');
});

In addition, there's a controller named HeadCtrl that needs to execute preGetTokenAndKey first in order to retrieve both the key and token required for subsequent REST API calls like getMyData.

app.controller('HeadCtrl', function (MyRestServices) {
  MyRestServices.preGetTokenAndKey().success(function(data) {
    var key = data.dataSection.key;
    var token = data.dataSection.token;
  });
});

The issue arises when I try to call getMyData from another controller without having access to both the key and token. Therefore, the solution involves waiting for the successful execution of preGetTokenAndKey first before passing these values to the MyRestServices provider. How can I effectively tackle these challenges?

Answer №1

To optimize the workflow, consider chaining them within your service. Create a custom promise in preGetTokenAndKey that is resolved by the $http call. Subsequent calls to preGetTokenAndKey() will simply return the already resolved data without triggering additional $http requests.

You can start with something like this:

app.provider('MyRestServices', function() {
  this.baseUrl = null;
  this.setBaseUrl = function(_baseUrl) {
      this.baseUrl = _baseUrl;
  };

  this.$get = ['$http', function($http) {
    var _baseUrl = this.baseUrl;
    var _tokenAndKey = {};

    function getMyData() {
      return preGetTokenAndKey().then(function (data) {
            return $http.get(_baseUrl + 'data1/?token=' + data.dataSection.token + '&key=' + data.dataSection.key);
      });
    }

    function preGetTokenAndKey() {
      if(!_tokenAndKey.set) {
           _tokenAndKey.deferred = $http.get(_baseUrl + 'keyAndToken/').then(function(data) {
                _tokenAndKey.set = true;
                return data;
           });
      }
      return _tokenAndKey.deferred.promise.then();
    }

    return {
      getMyData: getMyData,
      preGetTokenAndKey: preGetTokenAndKey
    };
  }];
});

Answer №2

I am facing an issue where I need to invoke the getMyData function from a different controller,

If this is the case, you can utilize $broadcast to inform another controller that the asynchronous call has been resolved and you now have the key/token

app.controller('HeadCtrl', function($rootScope, MyRestServices) {
    MyRestServices.preGetTokenAndKey().success(function(data) {
        var key = data.dataSection.key;
        var token = data.dataSection.token;

        $rootScope.$broadcast("getMyDataTrigger", {key: key,token: token}); 
    });
});

In the other controller, create a listener:

$rootScope.$on("getMyDataTrigger", function(event, data){

        if(data){
           MyRestServices.getMyData(data.key, data.token);
           // ...
        }

    });

Simply customize the getMyData function:

function getMyData(key, token) {
  return $http.get(_baseUrl + 'data1/?token=' + token + '&key=' + key);
}

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

Function executed many times during click action

I have developed a web application that allows users to input any keyword or statement and receive twenty results from Wikipedia using the Wikipedia API. The AJAX functionality is working perfectly. The app should dynamically create a DIV to display each r ...

The upload method in flowjs is not defined

I am a novice when it comes to flow.js and am currently using the ng-flow implementation. I have a specific task in mind, but I'm unsure if it's feasible or not, and if it is possible, how to achieve it. I've created a factory that captures ...

Troubleshooting Vercel and Express DELETE request cross-origin resource sharing problem

Currently, I am in the process of developing an API using Vercel and ExpressJS. The GET and POST endpoints are functioning properly, however, I encountered an issue with the DELETE endpoint. When attempting to access the endpoint from my client-side JavaSc ...

Creating Vue.js components dynamically

Is it possible to programmatically insert a modal component in Vue? For instance: Vue.component('modal', {...}) Then, in any component, is there a way to do something like this: Vue.component('login', { methods: { openLoginM ...

How can I deliver assets in React without the PUBLIC_URL showing up in the path?

I have set up a portfolio website that includes my resume. I am trying to make it so that when someone visits the route http://localhost:3000/resume.pdf, they can view my resume directly. The resume.pdf file is located in my public folder. However, instead ...

Alternating the tooltip icon based on the field's condition

Looking for a way to create a tooltip for an input field that involves changing icons based on certain conditions. An example scenario is the password field in a registration form. Seeking advice on the best approach to achieve this. Currently, here' ...

What could be causing "Unknown property" errors when using unicode property escapes?

The MDN website provides examples of matching patterns with unicode support, such as: const sentence = 'A ticket to 大阪 costs ¥2000 ...

The Vue plugin encountered an issue with an error message stating "Uncaught SyntaxError: Unexpected token

I'm excited to dive into using vue for my upcoming project. I decided to incorporate Hooper, an image carousel, and went ahead to install it using npm install hooper. To implement it in my script file, I included the following code: import { Hooper ...

Looking for a way to execute MySQL queries using promises in Protractor?

Is there a way to query a MySQL database using promises in Protractor? I have multiple queries that I need to execute during test execution, but my `executeSelectQuery` function always runs at the beginning of the test. How can I ensure it executes at the ...

Configuring the data source for an autocomplete feature in ReactJS Material UI

For one of my React components, I am utilizing the Material UI autocomplete feature. The data source is retrieved from the server asynchronously and has the following structure: const dataSource = [{ id: 001 firstName: 'fname', lastName: &apo ...

Customized style sheets created from JSON data for individual elements

One of the elements in the API requires dynamic rendering, and its style is provided as follows: "elementStyle": { "Width": "100", "Height": "100", "ThemeSize": "M", "TopMargin": "0", " ...

Retrieve the specific file path of a dependency within the node_modules directory

Can you help me find the exact path of a dependency within a specific node_modules package? Here's an example setup: |- node_modules/ |- <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d4a4b5b7bfb5b3b1f9b594e6fae5fae4"& ...

Data-bind knockout select knockout bind data

Hello! I am a beginner at using knockout and I have encountered an issue with data-binds and the "option" binding. My goal is to display two drop downs populated with data from my database. Surprisingly, I have managed to get the first drop down working pe ...

Tips for managing modal states in functional React components in React Native using React hooks

Utilizing React hooks to manage modal opening and closing, I encountered an issue with my code. The function 'handleAddClick' is supposed to open the modal when used on TouchableOpacity, while the function 'handleClose' should close the ...

How to creatively position custom arrows in a React JS Nuka Carousel

Seeking assistance on properly positioning custom arrows within the Nuka Carousel component. After combining the decorators, I found that both of my arrows are appearing side by side. How can I address this issue? My goal is to have one arrow positioned in ...

Initiate gapi.auth2 upon VueJs initialization

I am currently developing a Vue.js web application that allows users to connect with their Google accounts. The login process, both front-end and back-end, is functioning properly: the Google sign-in button is displayed, the user clicks on it, and their a ...

Is it more efficient to pass session variables through an ajax function, or should I access them directly within the script?

I am currently working on a page that utilizes an ajax function to retrieve updates from another page. The function requires the user's id, which is obtained from a session variable, to fetch any new updates. These updates are then displayed in a spec ...

classes_1.Individual is not a callable

I am facing some difficulties with imports and exports in my self-made TypeScript project. Within the "classes" folder, I have individual files for each class that export them. To simplify usage in code, I created an "index.ts" file that imports all class ...

Tips for correctly linking JS and CSS resources in Node.js/Express

I have a JavaScript file and a stylesheet that I am trying to link in order to use a cipher website that I created. Here is my File Path: website/ (contains app.js/html files and package json) website/public/css (contains CSS files) website/public/scri ...