0

I am reading data from a json file and storing it in an object in javascript , I am using d3js library to read the file.

This is what the raw data looks like in data.json file :

{
    "bitcoin": [
        {
            "24h_vol": null,
            "date": "12/5/2013",
            "market_cap": null,
            "price_usd": null
        },
        {
            "24h_vol": null,
            "date": "13/5/2013",
            "market_cap": null,
            "price_usd": null
        },
        {
            "24h_vol": "0",
            "date": "14/5/2013",
            "market_cap": "1500517590",
            "price_usd": "135.3"
        },...]
 "bitcoin_cash": [
        {
            "24h_vol": null,
            "date": "12/5/2013",
            "market_cap": null,
            "price_usd": null
        },
        {
            "24h_vol": null,
            "date": "13/5/2013",
            "market_cap": null,
            "price_usd": null
        },...]
    }

I read this and then filter some of the null entries out and also parse the date and Integer values respectively, This is the code for the same:

//Get data
d3.json("data/coins.json").then((data) => {

    console.log("original data", data.bitcoin);
        /*---
    original data (1633) [{…}, , …]

    [0 … 99]

    0: {24h_vol: null, date: "12/5/2013", market_cap: null, price_usd: null}
    1: {24h_vol: null, date: "13/5/2013", market_cap: null, price_usd: null}
    2: {24h_vol: "0", date: Tue May 14 2013 00:00:00 GMT-0400 (Eastern Daylight Time), market_cap: 1500517590, price_usd: 135.3}
    ...
    --------*/


    //Selector listener
    $("#coin-select").change(function() {
        var coinType =this.value;
        var coinData = data[coinType];
        var cleanData = coinData.filter((d) => {
                return (d.price_usd)
            }).map((d) => {
            d.price_usd =+ d.price_usd;
            d.market_cap =+ d.market_cap;
            d.date = parsedDate(d.date);
            return d;
        });
        console.log("cleanData", cleanData)

    /*------
    cleanData  (1631) [{…}, {…}, , …]
    [0 … 99]
    0: {24h_vol: "0", date: Tue May 14 2013 00:00:00 GMT-0400 (Eastern Daylight Time), market_cap: 1500517590, price_usd: 135.3}
    1: {24h_vol: "0", date: Wed May 15 2013 00:00:00 GMT-0400 (Eastern Daylight Time), market_cap: 1575032004, price_usd: 141.96}

    ---*/
    update(cleanData);
    });

    //Default to bitcoin
    $('#coin-select')
       .val('bitcoin')
       .trigger('change');

});

As you can see the console output , the original data has parsed values for date,market_cap and price_usd too, not sure why this is happening.

Thanks for you time.

PS: this doesn't only happens in chrome as suggested in the question : Is Chrome's JavaScript console lazy about evaluating arrays?

Snedden27
  • 1,870
  • 7
  • 32
  • 60
  • Objects are passed around by _Ref_, not _Val_. If you want to preserve the original, you'll need to perform your operation in a way which creates a new object, e.g. you could [spread the object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Syntax) `.map(d => ({...d, price_usd: d.price_usd + d.price_usd, market_cap: d.market_cap + d.market_cap, date: parsedDate(d.date)}))` – Paul S. Nov 09 '18 at 21:59
  • 1
    In your map, create a new object rather than modifying and returning the current one. – Kevin B Nov 09 '18 at 22:09
  • Possible duplicate of [Is Chrome's JavaScript console lazy about evaluating arrays?](https://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about-evaluating-arrays) – vnt Nov 09 '18 at 22:18
  • @vnt It doesn't seem like as it happens on other browsers too – Snedden27 Nov 11 '18 at 15:55
  • @KevinB that seem to work , but I still don't understand it completely , doens't have this line in the code: var coinData = data[coinType]; segregate the 'data' object from the 'coinData' object. don't seem to understand why using 'coinData' in map function object changes the original data object – Snedden27 Nov 11 '18 at 16:25

1 Answers1

1

Try something like this:

$("#coin-select").change(function() {
    var coinType = this.value;
    var coinData = data[coinType];
    var cleanData = coinData.filter(x => x.price_usd)
      .map(d => ({
        price_usd: d.price_usd =+ d.price_usd,
        market_cap: d.market_cap =+ d.market_cap,
        date: parsedDate(d.date)
      }));
    update(cleanData);
});

This makes sure you return a new object from your map so you do not mutate the original and also cleans up some of the explicit returns you had which are not needed.

Akrion
  • 18,117
  • 1
  • 34
  • 54
  • Not sure how you are using the arrow function for .map. copied letter by letter seems to give a syntax error – Snedden27 Nov 11 '18 at 16:18
  • There was an extra comma in the object literal. Try again – Akrion Nov 11 '18 at 18:03
  • yes it does but there seems to be a missing ending parenthesis too , can you change that and also if possible can you make the new object creation more explicit May its just my opinion but it might a little more discern-able for ecmascript6 noobs like me – Snedden27 Nov 12 '18 at 00:55