• Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
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.7k 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 Apr 28, 2017, 4:17 PM

    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 :-)

    S 1 Reply Last reply Apr 28, 2017, 5:46 PM Reply Quote 0
    • S Offline
      strawberry 3.141 Project Sponsor Module Developer @blaukon
      last edited by Apr 28, 2017, 5:46 PM

      @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
      • B Offline
        Beh
        last edited by Beh Apr 28, 2017, 6:23 PM Apr 28, 2017, 6:19 PM

        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 Apr 29, 2017, 4:49 PM

          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
          1 / 1
          • First post
            1/4
            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