Take current month range of dates from json response in jquery

Viewed 163

I am developing an application. I am getting a response from the AJAX request like this:

{
  "country": "italy",
  "timeline": {
    "cases": {
      "1/22/20": 0,
      "1/23/20": 0,
      "1/24/20": 0,
      "1/25/20": 0,
      "1/26/20": 0,
      "1/27/20": 0,
      "1/28/20": 0,
      "1/29/20": 0,
      "1/30/20": 0,
      "1/31/20": 2,
      "2/1/20": 2,
      "2/2/20": 2,
      "2/3/20": 2,
      "2/4/20": 2,
      "2/5/20": 2,
      "2/6/20": 2,
      "2/7/20": 3,
      "2/8/20": 3,
      "2/9/20": 3,
      "2/10/20": 3,
      "2/11/20": 3,
      "2/12/20": 3,
      "2/13/20": 3,
      "2/14/20": 3,
      "2/15/20": 3,
      "2/16/20": 3,
      "2/17/20": 3,
      "2/18/20": 3,
      "2/19/20": 3,
      "2/20/20": 3,
      "2/21/20": 20,
      "2/22/20": 62,
      "2/23/20": 155,
      "2/24/20": 229,
      "2/25/20": 322,
      "2/26/20": 453,
      "2/27/20": 655,
      "2/28/20": 888,
      "2/29/20": 1128,
      "3/1/20": 1694,
      "3/2/20": 2036,
      "3/3/20": 2502,
      "3/4/20": 3089,
      "3/5/20": 3858,
      "3/6/20": 4636,
      "3/7/20": 5883,
      "3/8/20": 7375,
      "3/9/20": 9172,
      "3/10/20": 10149,
      "3/11/20": 12462,
      "3/12/20": 12462,
      "3/13/20": 17660,
      "3/14/20": 21157,
      "3/15/20": 24747,
      "3/16/20": 27980,
      "3/17/20": 31506,
      "3/18/20": 35713,
      "3/19/20": 41035,
      "3/20/20": 47021,
      "3/21/20": 53578,
      "3/22/20": 59138,
      "3/23/20": 63927,
      "3/24/20": 69176,
      "3/25/20": 74386,
      "3/26/20": 80589,
      "3/27/20": 86498
    },
    "deaths": {
      "1/22/20": 0,
      "1/23/20": 0,
      "1/24/20": 0,
      "1/25/20": 0,
      "1/26/20": 0,
      "1/27/20": 0,
      "1/28/20": 0,
      "1/29/20": 0,
      "1/30/20": 0,
      "1/31/20": 0,
      "2/1/20": 0,
      "2/2/20": 0,
      "2/3/20": 0,
      "2/4/20": 0,
      "2/5/20": 0,
      "2/6/20": 0,
      "2/7/20": 0,
      "2/8/20": 0,
      "2/9/20": 0,
      "2/10/20": 0,
      "2/11/20": 0,
      "2/12/20": 0,
      "2/13/20": 0,
      "2/14/20": 0,
      "2/15/20": 0,
      "2/16/20": 0,
      "2/17/20": 0,
      "2/18/20": 0,
      "2/19/20": 0,
      "2/20/20": 0,
      "2/21/20": 1,
      "2/22/20": 2,
      "2/23/20": 3,
      "2/24/20": 7,
      "2/25/20": 10,
      "2/26/20": 12,
      "2/27/20": 17,
      "2/28/20": 21,
      "2/29/20": 29,
      "3/1/20": 34,
      "3/2/20": 52,
      "3/3/20": 79,
      "3/4/20": 107,
      "3/5/20": 148,
      "3/6/20": 197,
      "3/7/20": 233,
      "3/8/20": 366,
      "3/9/20": 463,
      "3/10/20": 631,
      "3/11/20": 827,
      "3/12/20": 827,
      "3/13/20": 1266,
      "3/14/20": 1441,
      "3/15/20": 1809,
      "3/16/20": 2158,
      "3/17/20": 2503,
      "3/18/20": 2978,
      "3/19/20": 3405,
      "3/20/20": 4032,
      "3/21/20": 4825,
      "3/22/20": 5476,
      "3/23/20": 6077,
      "3/24/20": 6820,
      "3/25/20": 7503,
      "3/26/20": 8215,
      "3/27/20": 9134
    }
  }
}

As you can, I have dates for the month of February and March in this response. I want to get only the range of dates with the corresponding value within the current month, that is March in this case. How can I achieve this in jQuery?

$.ajax({
  url: 'https://corona.lmao.ninja/v2/historical/italy',
  type: 'GET',
  dataType: 'JSON',
  success: function(data) {
    console.log('in');
    console.log(data);
  }
});
3 Answers

You may use Object.keys(), filter() & reduce() methods to acheive this like:

$.ajax({
  url: 'https://corona.lmao.ninja/v2/historical/italy',
  type: 'GET',
  dataType: 'JSON',
  success: function(data) {
    const date = new Date(),y = date.getFullYear(),m = date.getMonth();
    const firstDay = new Date(y, m, 1).getTime(), lastDay = new Date(y, m + 1, 0).getTime();
    const currentData = Object.keys(data.timeline.cases)
      .filter(key => firstDay <= new Date(key).getTime() && new Date(key).getTime() <= lastDay)
      .reduce((o, k) => { o[k] = data.timeline.cases[k]; return o }, {});
    console.log(currentData)
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Explanation:

  1. First inside ajax success method, we are trying to get first & last day of the current month, as we need those values to filter data.
  2. Then using Object.keys we get all the keys in data.timeline.cases as this holds all the date strings as key.
  3. Then using filter() method we get only the keys which are between first and last day of the current month.
  4. Then using reduce() method we are trying to reconstruct the data.timeline.cases object back, so that you can use it in your application.

To achieve this you can use $.each() to determine whether the key in the cases object is a date within the current month and use it to create a new object with those entities. Try this:

$.ajax({
  url: 'https://corona.lmao.ninja/v2/historical/italy',
  type: 'GET',
  dataType: 'JSON',
  success: function(data) {
    var currentMonth = new Date().getMonth();
    var currentMonthCases = {};
    $.each(data.timeline.cases, (k, v) => {
      if (new Date(k).getMonth() === currentMonth)
        currentMonthCases[k] = v;
    })
    
    console.log(currentMonthCases);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Using map, reduce, you can do is very easly. I have written a parser, will give you more stats. Please check.

const data = {
  country: "italy",
  timeline: {
    cases: {
      "1/22/20": 0,
      "1/23/20": 0,
      "1/24/20": 0,
      "1/25/20": 0,
      "1/26/20": 0,
      "1/27/20": 0,
      "1/28/20": 0,
      "1/29/20": 0,
      "1/30/20": 0,
      "1/31/20": 2,
      "2/1/20": 2,
      "2/2/20": 2,
      "2/3/20": 2,
      "2/4/20": 2,
      "2/5/20": 2,
      "2/6/20": 2,
      "2/7/20": 3,
      "2/8/20": 3,
      "2/9/20": 3,
      "2/10/20": 3,
      "2/11/20": 3,
      "2/12/20": 3,
      "2/13/20": 3,
      "2/14/20": 3,
      "2/15/20": 3,
      "2/16/20": 3,
      "2/17/20": 3,
      "2/18/20": 3,
      "2/19/20": 3,
      "2/20/20": 3,
      "2/21/20": 20,
      "2/22/20": 62,
      "2/23/20": 155,
      "2/24/20": 229,
      "2/25/20": 322,
      "2/26/20": 453,
      "2/27/20": 655,
      "2/28/20": 888,
      "2/29/20": 1128,
      "3/1/20": 1694,
      "3/2/20": 2036,
      "3/3/20": 2502,
      "3/4/20": 3089,
      "3/5/20": 3858,
      "3/6/20": 4636,
      "3/7/20": 5883,
      "3/8/20": 7375,
      "3/9/20": 9172,
      "3/10/20": 10149,
      "3/11/20": 12462,
      "3/12/20": 12462,
      "3/13/20": 17660,
      "3/14/20": 21157,
      "3/15/20": 24747,
      "3/16/20": 27980,
      "3/17/20": 31506,
      "3/18/20": 35713,
      "3/19/20": 41035,
      "3/20/20": 47021,
      "3/21/20": 53578,
      "3/22/20": 59138,
      "3/23/20": 63927,
      "3/24/20": 69176,
      "3/25/20": 74386,
      "3/26/20": 80589,
      "3/27/20": 86498
    },
    deaths: {
      "1/22/20": 0,
      "1/23/20": 0,
      "1/24/20": 0,
      "1/25/20": 0,
      "1/26/20": 0,
      "1/27/20": 0,
      "1/28/20": 0,
      "1/29/20": 0,
      "1/30/20": 0,
      "1/31/20": 0,
      "2/1/20": 0,
      "2/2/20": 0,
      "2/3/20": 0,
      "2/4/20": 0,
      "2/5/20": 0,
      "2/6/20": 0,
      "2/7/20": 0,
      "2/8/20": 0,
      "2/9/20": 0,
      "2/10/20": 0,
      "2/11/20": 0,
      "2/12/20": 0,
      "2/13/20": 0,
      "2/14/20": 0,
      "2/15/20": 0,
      "2/16/20": 0,
      "2/17/20": 0,
      "2/18/20": 0,
      "2/19/20": 0,
      "2/20/20": 0,
      "2/21/20": 1,
      "2/22/20": 2,
      "2/23/20": 3,
      "2/24/20": 7,
      "2/25/20": 10,
      "2/26/20": 12,
      "2/27/20": 17,
      "2/28/20": 21,
      "2/29/20": 29,
      "3/1/20": 34,
      "3/2/20": 52,
      "3/3/20": 79,
      "3/4/20": 107,
      "3/5/20": 148,
      "3/6/20": 197,
      "3/7/20": 233,
      "3/8/20": 366,
      "3/9/20": 463,
      "3/10/20": 631,
      "3/11/20": 827,
      "3/12/20": 827,
      "3/13/20": 1266,
      "3/14/20": 1441,
      "3/15/20": 1809,
      "3/16/20": 2158,
      "3/17/20": 2503,
      "3/18/20": 2978,
      "3/19/20": 3405,
      "3/20/20": 4032,
      "3/21/20": 4825,
      "3/22/20": 5476,
      "3/23/20": 6077,
      "3/24/20": 6820,
      "3/25/20": 7503,
      "3/26/20": 8215,
      "3/27/20": 9134
    }
  }
};

const parseDate = srt => {
  const [m, d, y] = srt.split("/");
  return new Date(d, m - 1, y).getMonth();
};
const toArray = obj => {
  const generator = function*() {
    for (let key in obj) {
      yield [obj[key], key];
    }
  };
  return {
    [Symbol.iterator]: generator,
    map: function(fn) {
      let result = [];
      for (let [value, key] of this) {
        result.push(fn(value, key));
      }
      return result;
    }
  };
};
const grouped = toArray(data.timeline.cases)
  .map((x, k) => [x, k])
  .reduce((m, c) => {
    const parsedDate = parseDate(c[1]);
    if (!m[parsedDate]) {
      m[parsedDate] = { cases: [], deaths: [], totalCases: 0, totalDeaths: 0 };
    }
    m[parsedDate].cases.push({ date: c[1], cases: c[0] });
    m[parsedDate].deaths.push({
      date: c[1],
      deaths: data.timeline.deaths[c[1]]
    });
    m[parsedDate].totalCases += c[0];
    m[parsedDate].totalDeaths += data.timeline.deaths[c[1]];
    return m;
  }, {});
// console.log(JSON.stringify(grouped, null, 2));
// For march
console.log(JSON.stringify(grouped[2], null, 2));
console.log(grouped[2].totalDeaths);
console.log(grouped[2].totalCases);
// For feb
console.log(JSON.stringify(grouped[1], null, 2));
console.log(grouped[1].totalDeaths);
console.log(grouped[1].totalCases);

Related