MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    A New Chapter for MagicMirror: The Community Takes the Lead
    Read the statement by Michael Teeuw here.

    Multiple requests within one function

    Scheduled Pinned Locked Moved Troubleshooting
    4 Posts 3 Posters 1.6k Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B Offline
      blaukon
      last edited by

      Hello community :-)

      I’m kinda despairing with this problem :-(
      The idea: requesting the system temperatures of all raspberrys listed in the config file (they are all running a flask server)
      But I can’t get the object working.

      node_helper gets the object from my config file:

       {
                              module: 'getTemps',
                              header: 'RPi Temperatures',
                              position: 'top_right',
                              config: {
                                       devices: [
                                                   {
                                                        url: 'http://10.0.0.83:2222/temp',
                                                        name: 'Alarmpi'
                                                   },
                                                   {
                                                        url: 'http://10.0.0.25:2222/temp',
                                                        name: 'Mediapi'
                                                   },
                                                   {
                                                        url: 'http://10.0.0.25:2222/temp',
                                                        name: 'Camerapi'
                                                   }
                                      ]
                              }
                      },
      

      my node_helper.js:

          getJSON: function(object) {
              var self = this;
              var data = object;
              console.log(data);
              for (var key in data) {
                      console.log(data[key]);
                      request({url: data[key].url, method: 'GET'}, function(error, response, body)
                      {
                              if (!error && response.statusCode == 200)
                              {
                                      data[key].temp=body;
                                      console.log(body);
                                      console.log(data);
                              }
                              else
                              {
                                      console.log(" Error: " + response.statusCode);
                                      data[key].temp = 'offline';
                              }
                      });
              }
              console.log(data);
              self.sendSocketNotification('received_values', data);
          }
      

      just one run creates two outputs and the final content of “data” is missing the temperature values.
      And as shown in the console output, the received temperature value is always added (it looks like temporary) to the last object in the list.

      [ { url: ‘http://10.0.0.83:2222/temp’, name: ‘Alarmpi’ },
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Mediapi’ },
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Camerapi’ } ]
      { url: ‘http://10.0.0.83:2222/temp’, name: ‘Alarmpi’ }
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Mediapi’ }
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Camerapi’ }
      [ { url: ‘http://10.0.0.83:2222/temp’, name: ‘Alarmpi’ },
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Mediapi’ },
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Camerapi’ } ]
      51.0
      [ { url: ‘http://10.0.0.83:2222/temp’, name: ‘Alarmpi’ },
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Mediapi’ },
      { url: ‘http://10.0.0.25:2222/temp’,
      name: ‘Camerapi’,
      temp: ‘51.0’ } ]
      51.5
      [ { url: ‘http://10.0.0.83:2222/temp’, name: ‘Alarmpi’ },
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Mediapi’ },
      { url: ‘http://10.0.0.25:2222/temp’,
      name: ‘Camerapi’,
      temp: ‘51.5’ } ]
      59.1
      [ { url: ‘http://10.0.0.83:2222/temp’, name: ‘Alarmpi’ },
      { url: ‘http://10.0.0.25:2222/temp’, name: ‘Mediapi’ },
      { url: ‘http://10.0.0.25:2222/temp’,
      name: ‘Camerapi’,
      temp: ‘59.1’ } ]

      (Mediapi and Camerapi have the same IP in this example)

      thanks for your help :-)

      strawberry 3.141S 1 Reply Last reply Reply Quote 0
      • strawberry 3.141S Offline
        strawberry 3.141 Project Sponsor Module Developer @blaukon
        last edited by

        @blaukon you assume that you have the value data already when you send the variable data to your module, but request is asynchronous and therefore you get most likely the data after you send the result

        Please create a github issue if you need help, so I can keep track

        1 Reply Last reply Reply Quote 0
        • BehB Offline
          Beh
          last edited by Beh

          As @strawberry-3-141 mentioned, the sendSocketNotification() function is called, before the callback function of your request is execuded and the content of data is created.

          You could either call the sendSocketNotification() function inside the callback function of the request or put the data variable into a promise (which is a much more elegant approach and produces good-readable asynchronous code).

          There are good explanations for promises, just google “promises simple explanation” (or similar).
          I can recommend this one: https://coligo.io/javascript-promises-plain-simple/

          Edit:
          Oh, and I would recommend the Bluebird.js library for promises. http://bluebirdjs.com/

          1 Reply Last reply Reply Quote 1
          • B Offline
            blaukon
            last edited by

            yeey, I got it working, although I don’t know why :P

             var NodeHelper = require("node_helper");
             var request = require('request');
             var Promise = require("promise");
             
             var result = new Array();
             
             module.exports = NodeHelper.create({
                start: function() {
                    console.log("Starting node_helper for module [" + this.name + "]");
                },
                // subclass socketNotificationReceived
                socketNotificationReceived: function(notification, payload){
                    if (notification === 'get_values') {
                        this.getJSON(payload);
                    }
                },
            		
            		
            	requestp: function(url, key, name) {
            		return new Promise(function (resolve, reject) {
            			request({url:url, method: 'GET'}, function (err, res, body) {
            				if (err) {
            					return reject(err);
            				} else if (res.statusCode !== 200) {
            					err = new Error("Unexpected status code: " + res.statusCode);
            					err.res = res;
            					return reject(err);
            				}
            				
            				result.push({url: url, name: name, temp: body});
            				resolve(body);
            			});
            		});
            	},
            		
                getJSON: function(object) {		
                    var self = this;
            		
            		for (var key in object) {
            			//console.log(object[key]);
            			
            			self.requestp(object[key].url, key, object[key].name).then(function (info) {
            					//console.log(info);
            				}, function (err) {
            					console.error("%s; %s", err.message, url);
            					console.log("%j", err.res.statusCode);
            			});
            			
            		}
            		//console.log(result);
            		self.sendSocketNotification('received_values', result);
            		result = [];
                }
             });
            

            I wasn’t able to add a “temp” property to the original object - it was actually added, but it did not want to work outside the .then function :(

            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post
            Enjoying MagicMirror? Please consider a donation!
            MagicMirror created by Michael Teeuw.
            Forum managed by Sam, technical setup by Karsten.
            This forum is using NodeBB as its core | Contributors
            Contact | Privacy Policy