KeykoYume
KeykoYume

Reputation: 2645

MEAN stack update view with Node/Express response

I have a MEAN stack dashboard app (server1) that communicates with a nodejs/express server (server2) which makes queries to a mongoDB. For example the user is supposed to select a month via the dashboard app calendar and this date will be sent to the nodejs/express server that will query mongo and return for example the number of times you went to the gym during that month.

I am getting the right response but I have problems updating the view (since http requests are asynchronous the request in the response in executed faster and thus updates my view with the wrong value)

I tackled my request as follows:

dashboard app - angular frontend

$scope.query = function () {
        console.log("I am hereee");
        var month = ("0" + ($scope.dt.getMonth() + 1)).slice(-2);
        var date = $scope.dt.getFullYear() + "" + month;
        var queryData = JSON.stringify({MemberID_Hash: $scope.memberNo, Date_Key_Month: date});
        console.log("data: ", queryData);
        console.log("url: ", expressQuery);
        $http({ //send query to node/express server
            method: 'POST',
            url: expressQuery,
            data: queryData,
            withCredentials: true,
            headers: {
                    'Content-Type': 'application/json; charset=utf-8'
            }
        }).then(function(response) { //read backend response
            console.log (">>>>>>>>");
            $http({
            method : "POST",
            url : "http://localhost:9000/sendToController"
            }).then(function mySucces(response) {
              console.log("responde.data: ", response.data);
              $scope.nrOfSwipes = response.data;
            }, function myError(response) { });
        });
    };  

dashboard app - back-end in express

var dataController = "test"; // used a global variable to save the response value to update my view (bad design => thus, any help/suggestions would be greatly appreciated)

module.exports = function(app) {

    // receives the response from server2 - !! this is executed 2nd
    app.post('/getQueryJson', function(request, response) {
        if(response.statusCode == 200) { 

          console.log("In routes.js TESTING......")
          console.log("This is your request: ", request.body);

          dataController = request.body;
          console.log("dataController1: ", dataController);
          response.send(request.body);
        }else{
          response.send(" Error code: " + response.statusCode);
        }
    });

    // updates the view - !! this is executed first
    app.post('/sendToController', function(request, response) {
        console.log("dataController2: ", dataController);
        response.send(dataController);
    });
};

The problem is the request takes longer to process and so my response which calls sendToController is executed first then getQueryJson. Any idea how I can change the way they are executed? or any idea if it possible I can send the response from /getQueryJson directly to the frontend controller without having to make another request to /sendToController?

I just started getting my hands on the MEAN stack so I realise this may sound like a basic question but I am really stuck.

Upvotes: 0

Views: 259

Answers (1)

Sridhar
Sridhar

Reputation: 11786

Though you've chained promises, the order differs for you because you're not returning Promise. Editing your code to enforce order.

$http({
  method: 'POST',
  url: expressQuery,
  data: queryData,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
}).then(() => {
  return $http({
    method: 'POST',  //read backend response
    url: 'http://localhost:9000/sendToController'
  });
}).then((response) => {
  console.log(`responde.data: ${response.data}`);
  $scope.nrOfSwipes = response.data;
}).catch((err) => {
  //if error occurs
  console.log('err', err.stack);
});

Examining your code further, I see that, call to sendToController doesn't take any input from getQueryJson. If that's the actual case. You can use Promise.all() on that.

Making this changes to your code.

Promise.all([
  $http({
    method: 'POST',
    url: expressQuery,
    data: queryData,
    withCredentials: true,
    headers: {
      'Content-Type': 'application/json; charset=utf-8'
    }
  }),
  $http({
    method: 'POST',  //read backend response
    url: 'http://localhost:9000/sendToController'
  })
]).then((responses)=> {
  let ctrlResponse = responses[1];
  console.log(`responde.data: ${ctrlResponse.data}`);
  $scope.nrOfSwipes = ctrlResponse.data;
}).catch((err) => {
  console.log('err', err.stack);
});

or any idea if it possible I can send the response from /getQueryJson directly to the frontend controller without having to make another request to /sendToController?

Yes. We can do that. You need to respond with object in json. But the code you've provided us seem to be placeholders. If you can merge them. It might look like

response.status(200).send({
    query: 'some string', // your getQueryJson response,
    controller: 'some more value' //sendToController
});

Upvotes: 2

Related Questions