-1

I loop through an array called accData and make a new array called WL and RF. I want to make it easy to maintain, but I have a problem. When I want to change the WL array data to CH2 and RF array data to DIG2, I have to type the script manually. This is my script

const accData = [
    { st: 'serijabo', path: 'serijabo.json', wl: 'CH1', rf: 'DIG1' },
    { st: 'sukabumi', path: 'sukabumi.json', wl: 'CH2', rf: 'DIG2' },
];

for (let i = 0; i < accData.length; i++) {
  const xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    const data = JSON.parse(xhr.responseText);

    let WL = [];
    let RF = [];
    for (let i = 0; i < data.length; i++) {
      WL.push(Number(data[i].CH1)); // this line
      RF.push(Number(data[i].DIG1)); // and this line
    }
  }
 }
}

I try to use ES6 template to solve it but it is not working because the template must be place in a string.

WL.push(Number(data[i].`${accData[i].wl}`)); //not working
RF.push(Number(data[i].`${accData[i].rf}`)); //not working

How can I solve this?

Waloy
  • 13
  • 7
  • Is that `Number()` really necessary? – Vilx- Aug 30 '19 at 18:02
  • Possible duplicate of [JavaScript object declaration syntax - variable names as properties](https://stackoverflow.com/questions/12607845/javascript-object-declaration-syntax-variable-names-as-properties) – r3wt Aug 30 '19 at 18:07
  • yes, because json returns string and i want to process number, so i convert it @Vilx- – Waloy Aug 30 '19 at 18:08
  • duplicate of https://stackoverflow.com/questions/11043026/variable-as-the-property-name-in-a-javascript-object-literal and so many hundreds of other questions about the same thing. – r3wt Aug 30 '19 at 18:08
  • You use `i` twice.... That is your major issue – epascarello Aug 30 '19 at 18:11
  • In javascript, there's a subtle difference between `number` and `Number`. I suggest using `parseInt()` instead. That will do what you think it does. – Vilx- Aug 30 '19 at 18:16
  • Or `parseFloat()`, if you're dealing with that. – Vilx- Aug 30 '19 at 18:18

1 Answers1

0

Have you tried using brackets instead of a dot? They should allow you to access properties via a string.

WL.push(Number(data[i][`${accData[i].wl}`]));
RF.push(Number(data[i][`${accData[i].rf}`]));
Telmo Trooper
  • 4,993
  • 1
  • 30
  • 35
  • 2
    Also `i` has been redefined in the callback. – Vilx- Aug 30 '19 at 17:56
  • 3
    Not to mention the whole string expression is totally unnecesary. Just do `data[i][accData[i].rf]` – Vilx- Aug 30 '19 at 18:01
  • the `data[i][accData[i].wl]` returns error "Uncaught TypeError: Cannot read property 'wl' of undefined" while the `data[i].CH1` works fine – Waloy Aug 30 '19 at 18:44
  • If you're getting that error it means the object `accData[i]` doesn't exist at some moment for you to access its `wl` property. You can write ```accData[i] && WL.push(Number(data[i][`${accData[i].wl}`]));``` so the code will only run when `accData[i]` exists. – Telmo Trooper Aug 30 '19 at 18:57
  • and the `(data[i]['{accData[i].wl}'])` returns NaN for every element – Waloy Aug 30 '19 at 19:03
  • You're typecasting the value of `(data[i]['{accData[i].wl}'])` to number in your code, if the value is something that can't be parsed as number then `Number()` will return `NaN` (not a number). – Telmo Trooper Aug 30 '19 at 19:05
  • In fact, `CH1`, `CH2`, `DIG1` and `DIG2` are values that can't be parsed directly to a number. If you want to get just the number part you'll have to clean these values, you could use a regular expression for that. – Telmo Trooper Aug 30 '19 at 19:06
  • You can do `Number((data[i]['{accData[i].wl}']).replace(/\D/g,''))`, which will only typecast your string to number after all non-digit values have been removed. – Telmo Trooper Aug 30 '19 at 19:09
  • first thank you for your respons, but i do not understand because i can get the number part when parsing json value using `data[i].CH1`. And i've tried the `accData[i] && WL.push(Number(data[i][`${accData[i].wl}`]));`, it returns only the last element of json not combine all the elements. – Waloy Aug 30 '19 at 19:17
  • `data[i].CH1` is a value that comes from your API's response, right? It probably comes as a number or a string containing only digits, so that's why it works. In your `accData` object, the values for `wl` are either `CH1` and `CH2`, which are strings containing not only numbers, but characters as well. – Telmo Trooper Aug 30 '19 at 19:21
  • I'm still confused, the `WL.push(Number(data[i]['CH1']));` works fine, but `WL.push(Number(data[i]['accData[i].wl']));` returns `NaN`, while `'accData[i].wl'` returns `CH1`. I'm using the same url but returns different result. Do you have an example or an article about this topic? I want to solve this issue. – Waloy Aug 30 '19 at 20:29
  • Are you writing ```data[i][`${accData[i].wl}`]``` or ```data[i]['accData[i].wl'])```? Because those are very different things. – Telmo Trooper Aug 30 '19 at 20:37
  • when I write ``accData[i] && WL.push(Number(data[i][`${accData[i].wl}`]));`` it returns only the first CH1 value, not all of them – Waloy Aug 31 '19 at 04:23
  • I get a clue when the ``accData[i] && WL.push(Number(data[i][`${accData[i].wl}`]));`` returns only the first CH1 value, so I set another for loop to return all CH1 value. @TelmoTrooper. – Waloy Sep 02 '19 at 08:12