I am inexperienced with lodash, but I believe it can help me transform data into a desired format. I have tried varying level of methods described in the documentation, but I can not wrap my head around everything. I've looked here on SO, a few blogs, and the documentation. I have tried combining groupby and map, but I was unable to resolve the issue. I was also unsure how to log the steps.
Here is what I want to do, I want to take the following array and turn it into the array after it. Can anyone point me in the right direction?
Original Data
var mockData = [
{
"notice_title": "Bad news",
"notice_text": "Server is down!",
"start_date": "2016-09-18T04:00:00Z"
},
{
"notice_title": "Weekly Reminder",
"notice_text": "Please read the assignment!",
"start_date": "2016-09-18T04:00:00Z"
},
{
"notice_title": "Sweet",
"notice_text": "This morning, the new edition of our blog hit stands!",
"start_date": "2016-09-19T04:00:00Z"
},
{
"notice_title": "Yeah",
"notice_text": "This is pretty cool",
"start_date": "2016-09-19T04:00:00Z"
}
Desired Data
var newMockData = [
{
"date": "JAN 18 2016",
"messages": [{
"notice_title": "Bad news",
"notice_text": "Server is down!",
"start_date": "2016-09-18T04:00:00Z"
},
{
"notice_title": "Weekly Reminder",
"notice_text": "Please read the assignment!",
"start_date": "2016-09-18T04:00:00Z"
}],
"date": "JAN 19 2016",
"messages": [{
"notice_title": "Sweet",
"notice_text": "This morning, the new edition of our blog hit stands!",
"start_date": "2016-09-19T04:00:00Z"
},
{
"notice_title": "Yeah",
"notice_text": "This is pretty cool",
"start_date": "2016-09-19T04:00:00Z"
}]
}]
Updated lodash
var result = _.chain(mockData)
.groupBy(function(item) {
return moment(item.start_date.substring(0,10)).format("MMM-DD-YYYY");
})
.map((value, key) => {
return {
date: key,
param: value
}
})
.value();
I did answer a very similar question yesterday, however, I will still provide an answer here by modifying the previous one
var mockData = [
{
"notice_title": "Bad news",
"notice_text": "Server is down!",
"start_date": "2016-09-18T04:00:00Z"
},
{
"notice_title": "Weekly Reminder",
"notice_text": "Please read the assignment!",
"start_date": "2016-09-18T04:00:00Z"
},
{
"notice_title": "Sweet",
"notice_text": "This morning, the new edition of our blog hit stands!",
"start_date": "2016-08-19T04:00:00Z"
},
{
"notice_title": "Yeah",
"notice_text": "This is pretty cool",
"start_date": "2016-09-19T04:00:00Z"
}
]
var result = _.chain(mockData)
.groupBy(datum => moment(datum.start_date).format("MMM DD YYYY").toLocaleUpperCase() )
.map((messages, date) => ({ date, messages })) //using ES6 shorthand to generate the objects
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.1/lodash.min.js"></script>
The key thing here is that when using _.groupBy, you can supply a function that defines how objects are collected together. In this case, this is using Moment.js in order to format the start_date of the messages into Month-day-year format:
moment(datum.start_date).format("MMM DD YYYY")`
this will parse the date of the message and output it in <Short month> <day> <year> format. See more on formatting in the documentation. This value is then converted to upper case to transform "Sep" to "SEP"
The second thing is just generating the new structure inside the .map. Since all the information needed is already present formatted like so
{
"Sep 18 2016": [{
"notice_title": "Bad news",
"notice_text": "Server is down!",
"start_date": "2016-09-18T04:00:00Z"
}, {
"notice_title": "Weekly Reminder",
"notice_text": "Please read the assignment!",
"start_date": "2016-09-18T04:00:00Z"
}],
"Aug 19 2016": [{
"notice_title": "Sweet",
"notice_text": "This morning, the new edition of our blog hit stands!",
"start_date": "2016-08-19T04:00:00Z"
}],
"Sep 19 2016": [{
"notice_title": "Yeah",
"notice_text": "This is pretty cool",
"start_date": "2016-09-19T04:00:00Z"
}]
}
It's a simple matter of getting the keys and turning them into a property and the values and being added as another property.
Related
I have a large json data that I have to parse and get object out of the following Json string. I added just top part of that large json data. I tried to parse it by
let obj = JSON.parse(this.state.data);
it doesn't work, it breaks with this msg "SyntaxError: Unexpected token L in JSON at position 0".
If I get the console.log by console.log(JSON.stringify(this.state.data, null, 2)); and try to validate output by online JSON validator, it says it is valid JSON data. Could you please tell me how can I parse it?
{
"content": [
{
"_id": 1,
"name": "Warehouse A",
"location": {
"lat": 47.13111,
"long": -61.54801
},
"cars": {
"location": "West wing",
"vehicles": [
{
"model": "GX",
"price": 27395.26,
"licensed": false,
"_id": 15,
"make": "Lexus",
"year_model": 2005,
"date_added": "2017-11-12T00:00:00.000+00:00"
},
{
"model": "Q",
"price": 6103.4,
"licensed": false,
"_id": 9,
"make": "Infiniti",
"year_model": 1995,
"date_added": "2017-11-13T00:00:00.000+00:00"
},
.........xxxxxx continue
Your variable this.state.data is not a JSON. It's a Javascript Object, just like JSON, So, Why not just use let obj = this.state.data;
I have bunch of objects in an array with format as below:
[
{
"card_details": {
"cardType": "gift"
},
"merchant_details": {
"merchantName": "Walter Heisenberg1",
"timeZone": "+05:30",
}
},
{
"card_details": {
"cardType": "coupon",
"cardTitle": "Coupon",
"messageUser": "Hi",
"punchCount": null,
"messageReachPunchLimit": "Get your Freebie!",
"merchantId": "59c214000e1a7825184cb813",
"expiryDate": "21 Sep 2019",
"discountPercent": "15",
"cardImageUrl": ""
},
"merchant_details": {
"merchantName": "Walter Heisenberg1",
"timeZone": "+05:30"
}
},
{
"card_details": {
"cardType": "punch",
"cardTitle": "BlueM2",
"messageUser": "Welcome!",
"expiryDate": "21 Sep 2019",
"punchCount": 25,
"messageReachPunchLimit": "Get your Freebie!",
"merchantId": "59c214000e1a7825184cb813",
"cardImageUrl": "http://139.59.179.111/cloopapi/undefined"
},
"merchant_details": {
"merchantName": "Walter Heisenberg1",
"timeZone": "+05:30"
}
}
]
I want to filter the objects based on cardType in the card_details object. But I want to search from the array. For example, if I search for ["coupon","gift"], then I should get the all the cards which have the card_details.cardType as coupon or gift.
I need to be able to do this in Node.js,i.e., Javascript.
You can use ES6 filter and includes functions here:
collection.filter(item => ['coupon', 'gift'].includes(item.card_details.cardType))
This is my loop in the Controller. I am trying to create and display a chart using Angular JS but I am unable to do so. The same graph is repeated in my view and upon page refresh, the graph changes. I want the response "Options" and "Votes" from the JSON. What mistake am I making?
for (var i = 0; i < response.response.options.length;i++) {
labels.push(response.response.options[i].options);
data.push(response.response.options[i].votes);
$scope.labels = labels;
$scope.data = [
data
];
This is my JSON. I have multiple calls and thus multiple JSONs like this are called from the API.
{
"response": {
"poll": {
"id": "17",
"story_id": "28346",
"user_id": "32425",
"question": "Who's your favorite actor?",
"status": "1",
"docs": "1473121969"
},
"options": [
{
"id": "59",
"options": "1. Hamza Ali Abbasi",
"image_url": "31xjr2a6f838gwqkw68p.png",
"doc": "1473121970",
"votes": "3"
},
{
"id": "60",
"options": "2. Emmad Irfani",
"image_url": "w9yhbtlr39pzn9d9bijf.png",
"doc": "1473121970"
},
{
"id": "61",
"options": "3. Shahbaz Shigri",
"image_url": "hxnbem90wtlo7eb8tuew.png",
"doc": "1473122087"
},
{
"id": "62",
"options": "4. Fawad Khan",
"image_url": "f9q6ud83bjt8ateazzzs.png",
"doc": "1473122111"
}
]
}
}
I think I know what you are getting at, with why it isn't working, and that may be your "data" array. Here is a jsfiddle that has it working and displaying the info you want:
https://jsfiddle.net/jwb9acqL/
If you look at the console output of the object in your original code, the output was:
[labels: Array[4], data: Array[1]]
Where the "votes" in data were for some reason put in another subarray:
$scope.data = [
data
];
I removed that extra array. See if that helps. If not, I would say you need to post the graph code.
I'm using Kimono to extract some data and create an API:
{
"name": "site update",
"count": 4,
"frequency": "Manual Crawl",
"version": 1,
"newdata": true,
"lastrunstatus": "success",
"thisversionstatus": "success",
"thisversionrun": "Sun Feb 07 2016 05:13:26 GMT+0000 (UTC)",
"results": {
"collection1": [
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9418/title-1/",
"text": "Title 1"
},
"pubDate": "February 6, 2016",
"index": 1,
"url": "http://www.tvtrailers.com/home/"
},
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9422/title-2/",
"text": "Title 2"
},
"pubDate": "February 6, 2016",
"index": 2,
"url": "http://www.tvtrailers.com/home/"
},
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9358/title-3/",
"text": "Title 3"
},
"pubDate": "February 5, 2016",
"index": 3,
"url": "http://www.tvtrailers.com/home/"
},
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9419/title-4/",
"text": "Title 4"
},
"pubDate": "February 5, 2016",
"index": 4,
"url": "http://www.tvtrailers.com/home/"
}
]
}
}
I'm trying to GET the value of href inside the title element, then
explode the string to obtain the id number (9418, 9422, 9358, 9419 on the code above) and create a new property with just the id number.
Or, if is not possible to create a new property, then I would like to just replace all the href string and keep the id number instead of the full href url.
Here is the code I'm using: -Not working
function getpost_number(data) {
var post_number = 0;
for(var href in data.results) {
data.results[href].forEach(function(row) {
var parts = row.split("/");
console.log(parts[5]+parts[6]);
});
};
data.post_number = post_number;
return data;
}
Result:
{
"error": "Bad Request",
"message": "Your function failed to evaluate because of Error: Object object has no method 'split'"
}
Also the code inspector inside kimono had 2 warnings:
On line 7: Don't make functions within a loop.
On line 8: Unnecessary semicolon
I appreciate any help and directions to figure out what's wrong with the code above,
thank you.
Addendum - new attempt
Here is the updated function I'm using with the code provided by Trincot on the comments below:
function addPostNumbers(data) {
for(var collection in data.results) {
data.results[collection].forEach(function(row) {
if (parts = row.title.href.match(/\/(\d+)\//)) {
row.title.post_number = parts[1];
}
});
}
}
Output:
{
"error": "Bad Request",
"message": "Your function failed to evaluate because of Error: parts is not defined"
}
Kimono Inspector warnings
line 5: Assignment in conditional expression.
line 8: Don't make functions within a loop.
The data you provided originally was not valid JSON, as it had more closing braces than opening ones, and it had some curly double quotes. This was fixed in your question later.
Here is a function that will add the post_number property in the title objects, provided that the href property contains a folder name that is numerical.
When you run this snippet, it will output the result (JSON) with the additional properties:
function addPostNumbers(data) {
var collection, rows, i, parts;
for (collection in data.results) {
var rows = data.results[collection];
for (i=0; i<rows.length; i++) {
parts = rows[i].title.href.match(/\/(\d+)\//);
if (parts) {
rows[i].title.post_number = parts[1];
}
}
}
return data;
}
// test data
var data = {
"name": "site update",
"count": 4,
"frequency": "Manual Crawl",
"version": 1,
"newdata": true,
"lastrunstatus": "success",
"thisversionstatus": "success",
"thisversionrun": "Sun Feb 07 2016 05:13:26 GMT+0000 (UTC)",
"results": {
"collection1": [
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9418/title-1/",
"text": "Title 1"
},
"pubDate": "February 6, 2016",
"index": 1,
"url": "http://www.tvtrailers.com/home/"
},
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9422/title-2/",
"text": "Title 2"
},
"pubDate": "February 6, 2016",
"index": 2,
"url": "http://www.tvtrailers.com/home/"
},
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9358/title-3/",
"text": "Title 3"
},
"pubDate": "February 5, 2016",
"index": 3,
"url": "http://www.tvtrailers.com/home/"
},
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9419/title-4/",
"text": "Title 4"
},
"pubDate": "February 5, 2016",
"index": 4,
"url": "http://www.tvtrailers.com/home/"
}
]
}
};
// don't add this to your code. Kimono will do this (I suppose):
addPostNumbers(data);
// write result in document, don't add this in your own code
document.write('<pre>' + JSON.stringify(data, null, 2) + '</pre>');
Concerning the warnings you received:
On line 7: Don't make functions within a loop.
You can ignore this warning. This is intended to avoid that the runtime has to create a function again and again, because it is defined within a loop. Here it concerns the forEach callback function, where the forEach call appears in a loop itself. However, with the forEach construct most runtimes will parse this efficiently.
On line 8: Unnecessary semicolon
This concerns the semi-colon after the closing brace of your for-loop. You should remove that one.
Addendum - feed back
You tried a previous version of my code (present now in your question) and listed some problems raised by Kimono, which seems to have its own Javascript parser and to apply stricter rules than the browser:
line 5: Assignment in conditional expression.
I have updated the above code, moving the assignment out of the conditional expression.
line 8: Don't make functions within a loop.
I had written earlier that this warning can be ignored, but now I have replaced the foreach loop as a standard for loop, so you should not get this warning any more.
line 16: document.write can be a form of eval
The calls to the functions addPostNumbers and document.write are only in my snippet to demo the solution. That part of the code is not intended to be used in your code.
"message": "Your function failed to evaluate because of Error: parts is not defined"
I added a var statement in the code above to avoid this.
I also added a return statement, as Kimono might need that as well, I don't know.
Your row is going to look like this:
{
"title": {
"href": "http://www.tvtrailers.com/scenes/view/id/9358/title/“,
"text": "Title 1"
},
"pubDate": "February 5, 2016",
},
"index": 1,
"url": "http://www.tvtrailers.com/videos/thismonth/bydate/"
}
Which means you want to dig deeper and split on row.title.href
Also, I'm not sure which pieces your are hoping to retrieve, but parts[5] will equal "id" and parts[6] will equal 9358. That is because the // after http: will create an empty item between "http:" and "www.tvtrailers.com".
In other words you split array will look like this:
["http:", "", "www.tvtrailers.com", "scenes", "view", "id", "9358", "title", ""]
I need to access temperature and append it to my page If these are all objects then I suppose I cant use an index since the order doesnt matter, which is throwing me off.
{
"response": {
"version": "0.1",
"termsofService": "http://www.wunderground.com/weather/api/d/terms.html",
"features": {
"conditions": 1
}
},
"current_observation": {
"image": {
"url": "http://icons-ak.wxug.com/graphics/wu2/logo_130x80.png",
"title": "Weather Underground",
"link": "http://www.wunderground.com"
},
"display_location": {
"full": "Toms River, NJ",
"city": "Toms River"
},
"observation_location": {
"full": "Stonehedge, Toms River, New Jersey",
"city": "Stonehedge, Toms River",
"state": "New Jersey",
"country": "US"
},
"estimated": {},
"station_id": "KNJTOMSR5",
"observation_time": "Last Updated on April 11, 10:56 PM EDT",
"observation_time_rfc822": "Fri, 11 Apr 2014 22:56:39 -0400",
"observation_epoch": "1397271399",
"local_time_rfc822": "Fri, 11 Apr 2014 22:56:40 -0400",
"local_epoch": "1397271400",
"local_tz_short": "EDT",
"local_tz_long": "America/New_York",
"local_tz_offset": "-0400",
"weather": "Clear",
**"temperature_string": "59.6 F (15.3 C)"**
}
}
My javascript right now is plainly this since I havent figured out how to access this item yet
$(function() {
$("#getzip").submit(function() {
var zip_data =$(this).serialize();
$.getJSON("get_weather.php",null, function(data); {
I need to append this to the dom of my page, I think it shouldlook something like this?
(#output).append(data.temperature_string);
To get json object into javascript.
Use like this.
In Php
$json ='{"temperature":"36 c"}';
In Javascript
$.post("get_weather.php",null, function(data){
var temperature = data.temperature; // here you'll get temperature from json into variable
console.log(temperature);
},"json");
That's all
console.log(data["temperature_string"]) should access to that data.