# JSON problem

**URL:** <https://community.homey.app/t/json-problem/55372>\
**Category:** Apps\
**Created:** [November 24, 2021, 8:29pm UTC](https://community.homey.app/t/json-problem/55372 "2021-11-24T20:29:20Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![szuperp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/szuperp/32/47661_2.png) [@szuperp](https://community.homey.app/u/szuperp)\
**Post date:** [November 24, 2021, 8:29pm UTC](https://community.homey.app/t/json-problem/55372/1 "2021-11-24T20:29:20Z")

</div>

I cant use JSON on the usualy way. I have a problem with the following code:

```auto
if (inJSON != "") {        
        var each;
        for (each in inJSON)
        {
          this.log(each);
          if (each == 'sensors') {
           // this.log(inJSON[each]);
            this.log(inJSON['sensors']); // this line is working
          }
        }
        this.log(inJSON['sensors']); // this line throws error: TypeError: Cannot read property 'sensors' of undefined
      }

```

there is two same line, but only the first is working… ☹  
Any idea?

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [November 25, 2021, 7:06am UTC](https://community.homey.app/t/json-problem/55372/3 "2021-11-25T07:06:59Z")

</div>

Where is `inJSON` coming from? The issue is the context in which your code is running, not the code itself.

---

<div class="post-metadata">

**Author:** ![szuperp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/szuperp/32/47661_2.png) [@szuperp](https://community.homey.app/u/szuperp)\
**Post date:** [November 25, 2021, 8:07am UTC](https://community.homey.app/t/json-problem/55372/4 "2021-11-25T08:07:24Z")

</div>

Does it matter? In that point (where it throws the error), if I just print the JSON out to the console, there is no problem.  
This is just a simplified example code to find, and show the problem…

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [November 25, 2021, 12:26pm UTC](https://community.homey.app/t/json-problem/55372/5 "2021-11-25T12:26:11Z")

</div>

> [@szuperp](#):
>
> This is just a simplified example code to find, and show the problem…

No, it doesn’t. I rewrote your simplified example to test it:

```auto
const inJSON = { foo: 'bar', sensors : 'xxx' };

this.log = console.log;

if (inJSON != "") {        
  var each;
  for (each in inJSON)
  {
    this.log(each);
    if (each == 'sensors') {
      // this.log(inJSON[each]);
      this.log(inJSON['sensors']); // this line is working
    }
  }
  this.log(inJSON['sensors']); // this line throws error: TypeError: Cannot read property 'sensors' of undefined
}

```

This works just fine. Like I said, your issue is not with this code but with the context in which it is used.

---

<div class="post-metadata">

**Author:** ![szuperp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/szuperp/32/47661_2.png) [@szuperp](https://community.homey.app/u/szuperp)\
**Post date:** [November 26, 2021, 8:16am UTC](https://community.homey.app/t/json-problem/55372/6 "2021-11-26T08:16:50Z")

</div>

ok. here is my full app.js.  
It connects to myIO server, and ask a JSON (inJSON) (first, with descriprions, after that a faster same JSON, without descriptions) in the setInterval(). This is a string, parsing to JSON ), and refreshing the server\_data variable (it is a JSON).  
My problem is, I can’t reach this JSON from the driver.js and from the device.js… (I tried it many ways)  
So if the server\_data is refreshed… it is set to the settings… (homey.settings.set(‘server\_data’, server\_data)😉  
And I can red that from other .js files… so it is working now… but a example at the end is throwing the error…

```auto
'use strict';

const Homey = require('homey');
const { createSecureContext } = require('tls');
var XMLHttpRequest = require('xhr2');
var server_data;

class myIO_App extends Homey.App {

  /**
   * onInit is called when the app is initialized.
   */
  async onInit() {
    
    var inJSON;
    var _responseTXT;
    var string2send;
    var updated_settings;

    // get settings variables
    var defaultSettings = this.homey.settings.get('defaultSettings');
    var address = this.homey.settings.get('address');
    var http_port = this.homey.settings.get('http_port');
    var app_port = this.homey.settings.get('app_port');
    var username = this.homey.settings.get('username');
    var password = this.homey.settings.get('password');
    
    // if it is the first time to start app, fill the settings with default variables
    if (defaultSettings == null) {
      this.homey.settings.set('address', '192.168.1.170');
      this.homey.settings.set('http_port', '80');
      this.homey.settings.set('app_port', '843');
      this.homey.settings.set('username', 'admin');
      this.homey.settings.set('password', 'admin');
      this.homey.settings.set('defaultSettings', 'set');
    }    
    
    this.homey.settings.set('updated_settings', 'true'); // set this from the index.htm to true
    this.homey.settings.set('server_data', "");

    // refreshing the server_data JSON
    setInterval(() => {                                 
      
      updated_settings = this.homey.settings.get('updated_settings');

      if (updated_settings == 'true') { //if index.html changed the settings or first turn
        this.homey.settings.set('server_data', "");
        address = this.homey.settings.get('address');
        http_port = this.homey.settings.get('http_port');
        app_port = this.homey.settings.get('app_port');
        username = this.homey.settings.get('username');
        password = this.homey.settings.get('password');
        //log settings variables
        this.log(address+" "+http_port+" "+app_port+" "+username+" "+password);
        string2send = "/d_sens_out.json";
        this.log("Settings_updated");
        this.homey.settings.set('updated_settings', 'false');
      } else {
        string2send = "/sens_out.json";
      }

      //this.log('Try to connect to myIO server');

      var request = new XMLHttpRequest();
      request.open('POST', "http://" + address + ":" + http_port + string2send, true);
      var enc = Buffer.from(username + ":" + password).toString('base64');
      request.setRequestHeader("Authorization", "Basic " + enc);
      var _tempThis = this; // because I will need it in the next function.
      request.onload = function () {       
        _responseTXT = this.responseText;        
        try {
          inJSON = JSON.parse(_responseTXT);          
          if (string2send == "/d_sens_out.json"|| server_data==null || server_data=="") {
            server_data = JSON.parse(JSON.stringify(inJSON));
          } else if (server_data!=null && server_data!=""){
            
            var key, number, element;
            for (key in inJSON) {
              if (key == 'relays') {
                for (number = 0; number < Object.keys(inJSON[key]).length; number++ ) {
                  for (element in inJSON[key][number]) {
                    server_data[key][number][element] = inJSON[key][number][element];                      
                  }                    
                }
              }          
            }            
          }          
          console.log("succesfull server_data update: " + server_data['relays'][0]['state']);
          _tempThis.homey.settings.set('server_data', server_data);
        }
        catch (e) {
          console.log("JSON parse error: "+e);        
        }        
      };
      // this is just a simple example to show the anomaly
      if (inJSON != "") {        
        var each;
        for (each in inJSON)
        {
          this.log(each);
          if (each == 'sensors') {
            this.log(inJSON[each]);
            this.log(inJSON['sensors']); // this line is working
          }
        }
        this.log(inJSON['sensors']); // this line throws error: TypeError: Cannot read property 'sensors' of undefined
      }

          try {
            request.send();
            console.log("request ok.");
          } catch (e) {
            console.log("request error: " + e);
          }          
    }, 5000);

    
    
    this.log('MyApp has been initialized');
  }  
  
}

module.exports = myIO_App;

```

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [November 26, 2021, 9:32am UTC](https://community.homey.app/t/json-problem/55372/7 "2021-11-26T09:32:38Z")

</div>

The location of your example code is outside the (asynchronous) `onload` handler. Only _inside_ the `onload` handler can you be sure that `inJSON` is initialized.

To make your life easier, I would suggest dropping `XMLHttpRequest` (which is a browser API anyway) and use a Promise-based module for HTTP requests, like [`http.min`](https://github.com/matjaz/node-http.min):

```auto
const http = require('http.min');
…
try {
  const inJSON = await http.post({
    uri: "http://" + address + ":" + http_port + string2send,
    json: true,
    headers: {
      authorization: 'Basic ' + Buffer.from(username + ":" + password).toString('base64')
    }
  });
  ...
} catch(e) {
  console.log('HTTP request error', e);
}

```

---

<div class="post-metadata">

**Author:** ![szuperp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/szuperp/32/47661_2.png) [@szuperp](https://community.homey.app/u/szuperp)\
**Post date:** [November 26, 2021, 10:01am UTC](https://community.homey.app/t/json-problem/55372/8 "2021-11-26T10:01:27Z")

</div>

thank you! I will change it.

---

<div class="post-metadata">

**Author:** ![szuperp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/szuperp/32/47661_2.png) [@szuperp](https://community.homey.app/u/szuperp)\
**Post date:** [November 26, 2021, 6:29pm UTC](https://community.homey.app/t/json-problem/55372/9 "2021-11-26T18:29:56Z")

</div>

Unfortunately, I cant make it work ☹  
it has something problem with the await …

SyntaxError: await is only valid in async function

But if I delete the await, it has more other problems… ☹  
my code is:

```auto
'use strict';

const Homey = require('homey');
const { createSecureContext } = require('tls');
var XMLHttpRequest = require('xhr2');
var server_data;
const http = require('http.min');

class myIO_App extends Homey.App {

  /**
   * onInit is called when the app is initialized.
   */
  async onInit() {
    
    //var inJSON;
    //var _responseTXT;
    var string2send;
    var updated_settings;

    // get settings variables
    var defaultSettings = this.homey.settings.get('defaultSettings');
    var address = this.homey.settings.get('address');
    var http_port = this.homey.settings.get('http_port');
    var app_port = this.homey.settings.get('app_port');
    var username = this.homey.settings.get('username');
    var password = this.homey.settings.get('password');
    
    // if it is the first time to start app, fill the settings with default variables
    if (defaultSettings == null) {
      this.homey.settings.set('address', '192.168.1.170');
      this.homey.settings.set('http_port', '80');
      this.homey.settings.set('app_port', '843');
      this.homey.settings.set('username', 'admin');
      this.homey.settings.set('password', 'admin');
      this.homey.settings.set('defaultSettings', 'set');
    }    
    
    this.homey.settings.set('updated_settings', 'true'); // set this from the index.htm to true
    this.homey.settings.set('server_data', "");

    // refreshing the server_data JSON
    setInterval(() => {                                 
      
      updated_settings = this.homey.settings.get('updated_settings');

      if (updated_settings == 'true') { //if index.html changed the settings or first turn
        this.homey.settings.set('server_data', "");
        address = this.homey.settings.get('address');
        http_port = this.homey.settings.get('http_port');
        app_port = this.homey.settings.get('app_port');
        username = this.homey.settings.get('username');
        password = this.homey.settings.get('password');
        //log settings variables
        this.log(address+" "+http_port+" "+app_port+" "+username+" "+password);
        string2send = "/d_sens_out.json";
        this.log("Settings_updated");
        this.homey.settings.set('updated_settings', 'false');
      } else {
        string2send = "/sens_out.json";
      }

      try {
        const inJSON = http.post({
          uri: "http://" + address + ":" + http_port + string2send,
          json: true,
          headers: {
            authorization: 'Basic ' + Buffer.from(username + ":" + password).toString('base64')
          }
        });
       
        if (string2send == "/d_sens_out.json"|| server_data==null || server_data=="") {
          server_data = JSON.parse(JSON.stringify(inJSON));
        } else if (server_data!=null && server_data!=""){
          var key, number, element;
          for (key in inJSON) {
              for (number = 0; number < Object.keys(inJSON[key]).length; number++ ) {
                for (element in inJSON[key][number]) {
                  server_data[key][number][element] = inJSON[key][number][element];                      
                }                    
              }       
          }            
        } 
        if (server_data != null && server_data != "") {
          console.log("succesfull server_data update: " + server_data['relays'][0]['description'] + " : " + server_data['relays'][0]['state']);
          console.log("succesfull server_data update: " + server_data['PWM'][0]['description'] + " : " + server_data['PWM'][0]['state']);
          this.homey.settings.set('server_data', server_data);
        }
      } catch(e) {
        console.log('HTTP request error', e);
      }
    }, 5000);

  
    
    this.log('myIO_App has been initialized');
  }  
  
}

module.exports = myIO_App;

```

---

<div class="post-metadata">

**Author:** ![Adrian\_Rockall](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/adrian_rockall/32/13209_2.png) [@Adrian\_Rockall](https://community.homey.app/u/Adrian_Rockall)\
**Post date:** [November 26, 2021, 6:41pm UTC](https://community.homey.app/t/json-problem/55372/10 "2021-11-26T18:41:38Z")

</div>

> [@szuperp](#):
>
> `setInterval(() => {`

Try  
`setInterval(async() => {`

---

<div class="post-metadata">

**Author:** ![szuperp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/szuperp/32/47661_2.png) [@szuperp](https://community.homey.app/u/szuperp)\
**Post date:** [November 26, 2021, 7:32pm UTC](https://community.homey.app/t/json-problem/55372/11 "2021-11-26T19:32:11Z")

</div>

it seems working 🙂 Thank You very much!
