Convert JSON naming schema in Ember - javascript

I have an application where I retrieve JSON data from a server. Unfortunately the JSON data is formatted as such:
"Product_Group" : [
{
"Product_Group_ID" : "396xx",
"Product_Group_SEO_Copy" : "Not Included in JSON",
"Product_Group_Title" : "Some awesome Title",
"Products" : [
{
"On_Sale_Date" : "04\/28\/09 00:00:00.000",
"ISBN" : "97800617737xx",
"Title" : "A Disgraceful Affair",
//rest of the it follows
Ember throws errors when trying to use Capitalized JSON objects in a template. Specifically the Uncaught TypeError: Cannot read property 'unchain' of undefined error. This is related to this issue noted on the Github Ember site.
My question, how can I convert all the titles from the server into camelCase? I don't have access to the server to change things on that end, so it will have to be client side. I've looked into the DS.RESTSerializer but I don't understand it enough to know if that is what I should be using.

DS.RESTSerializer is exactly what you want to use. You can easily transform the keys of your attributes by using the keyForAttribute hook. You may also need to change the attribute name of your root node Product_Group to something like productGroup. You can do this with extractArray.
A serializer such as this might just do the trick:
App.ProductGroupSerializer = DS.RESTSerializer.extend({
extractArray: function(store, type, payload) {
return this._super(store, type, {
productGroup: payload['Product_Group']
});
},
keyForAttribute: function(attr) {
return Ember.String.camelize(attr);
}
});

Related

Is it possible to move a particular JSON key to the top of the JSON using Javascript/VuejJS/Nodejs package?

I have a web application built using the Vuejs within that I am obtaining a JSON from the Java backend service which has a format something like this:
{
"a" : "Value-A",
"c" : "Value-C",
"b" : "Value-B",
"schema" : "2.0"
}
Before displaying the result to the user I would like to move the schema to the top so that it would be easy for the user to read and I want it to look something like this:
{
"schema" : "2.0",
"a" : "Value-A",
"c" : "Value-C",
"b" : "Value-B"
}
As we can see only schema position has changed, the rest of the JSON as it is.
Please Note:
I am aware the JSON order does not matter but I am doing this for better readability purposes. If there is a way then it would be really useful for the reader to understand the JSON better.
I want to know if there is a direct way to do it rather than looping over the JSON, as my created JSON in the real application can be pretty large.
All I want to do is move the schema to the top of the JSON. The rest of the JSON can be as it is I do not want to make any modifications to it.
Is there a way to do this using vanilla Javascript or using some Nodejs library as I am using the Vuejs?
I would really appreciate it if there was a way to do it or is there any workaround for this.
A very simplistic approach could be to stringify a new object.
const myObject = {
"a" : "Value-A",
"c" : "Value-C",
"b" : "Value-B",
"schema" : "2.0"
};
console.log(
JSON.stringify({
schema: myObject.schema,
...myObject
}, null, 2)
);
My suggestion is almost the same as the accepted answer but without using JSON.stringify():
const myObject = {
"a" : "Value-A",
"c" : "Value-C",
"b" : "Value-B",
"schema" : "2.0"
};
const myReorderedObject = {
schema: '',
...myObject
};
console.log(myReorderedObject);

Meteor render data from embeded, nested collection

I've been trying to get data out of a nested collection without any luck, besides using the dot notation from the html nothing seems to work.
What I want basically is to soley fetch the data I need from a nested collection. I'm trying to build a file upload for images and audio files and then a simple way to use the files. I'm using the cfs:standard-packages and cfs:filesystem packages.
The code below shows a working example of what I don't want, eg fetching the whole file object and retrieving the data in the html. If I could use the dot notation in the mongo command somehow would be perfect. I also could settle for _each but I would prefer fetching just the data I need on each db call. As you can see I'm passing an id for the whole file object here. Uploads.find({_id:Session.get('getpic')}); BTW, the actual file is stored in a folder on my local server.
The collection:
{
"_id" : "DXFkudDGCdvLpPALP",
"original" : {
"name" : "drink.png",
"updatedAt" : ISODate("2015-04-30T07:14:56.000Z"),
"size" : 127944,
"type" : "image/png"
},
"uploadedAt" : ISODate("2015-07-11T21:53:32.526Z"),
"copies" : {
"uploads" : {
"name" : "drink.png",
"type" : "image/png",
"size" : 127944,
"key" : "uploads-DXFkudDGCdvLpPALP-drink.png",
"updatedAt" : ISODate("2015-07-11T21:53:32.000Z"),
"createdAt" : ISODate("2015-07-11T21:53:32.000Z")
}
}
}
HTML
<template name="renderImages">
{{#each showpic}}
<img width="300" height="300" src="/projectuploads/{{copies.uploads.key}}"/>
{{/each}}
Javascript:
Template.renderImages.helpers({
showpic: function() {
return Uploads.find({_id:Session.get('getpic')});
}
});
specify the returned fields in the find query like so
return Uploads.find({_id:Session.get('getpic')}, { fields: {'copies.uploads.key': 1} } );
but a word on that. here you query minimongo (on the client), which is in the browsercache so it's basically free. take care to publish only those fields to the client that you actually want there.

Ember RESTAdapter with custom JSON format

I'm currently enjoying diving into Ember and learning a complete Front End MVC solution.
Currently, I'm a little stumped on getting data from our API as it doesn't follow the standard required by Ember's Adapter. Currently, our team are unable to change the structure of the API / JSON response due to the dependencies of third party applications.
RESTAdapter is looking for JSON like this:
{
'episodes' : [
{
id : '1',
title : 'my first title'
}
]
}
Unfortunately all we get back is an array with each episode as an object, i.e. it cannot be a key with a value of array of objects.
[
{
id : 1,
title : 'my first title'
},
{
id : 2,
title : 'my second title'
}
]
Can anyone provide assistance on how to extend DS.RESTAdapter to follow this format?
Again, our server devs cannot change the API so we have to take the JSON response as is.
Thanks
Override extractArray in your serializer. You can then modify the payload to match what ember data is looking for.
App.ApplicationSerializer = DS.RESTSerializer.extend({
extractArray: function(store, type, payload){
var plural = Ember.String.pluralize(type.typeKey),
fixed = {};
fixed[plural] = payload;
return this._super(store, type, fixed);
}
});
Example: http://emberjs.jsbin.com/OxIDiVU/953/edit

ui-data contracts: client side extended validation of json data

I am in a few situations where json I am getting from services and database calls, created by another group, are giving me invalid data combinations, and causing many unintended errors downstream.
Given in the small example below, if the "rowContent" field is equal to "1", it's corresponding "row" needs to be a populated javascript object. "rowContent1" and "row1", and "rowContent2" and "row2" are correct. "rowContent3" and "row3" is not.
I concede the structure of this json is not fantastic. Ok it's a little wacky. It's fairly close to what I am dealing with in production. I have little control over it.
Are there data driven ways to describe json data relationships like this, that validate, before I start trying to use non-existent data in "row3"?
Or, what would you recommend I do in this situation?
thanks much,
-Larry
{ "table" : [
{
"aRowContent" : {
"rowContent1" : "1",
"rowContent2" : "0",
"rowContent3" : "1",
},
"row1" : {
"myRowValue" : "red"
},
"row2" : null,
"row3" : null
}
]
}
Not with JSON Schema, certainly. JSON Schema validates the structure of JSON data without cross-referencing to other bits of data.
I think the issue might be the redundancy in your data structure- why do you need /table/0/aRowContent/rowContent1 when you can deduce the same information from a null-check of /table/0/row1?

Backbone relational lazy loading

I'm using Backbone with my RESTful JSON API in order to create an app that works with posts and their comments. I've been trying to get Backbone Relational to work, but run into problems with my Lazy loading.
I load up a list of posts, without the related comments. On click of an post in the list, I open up a view that fetches the full Post, comments included, and renders this.
I've got 2 Backbone.RelationModels, Posts and Comments. The post relation to the comment is setup as folows:`
relations: [{
type: Backbone.HasMany,
key: 'comments',
relatedModel: 'Comment',
includeInJSON: true, // don't include it in the exporting json
collectionType: 'Comments'
}]
Now the problem I'm facing is that the relationships are initialized as soon as I retrieve my list, that do not contain the comments yet. I load up the full data later, by fetching the model by it's URI. However, the relationships don't seem to reinitialise, calling Posts.get(1).get('comments') returns a Comments collection that is empty!
Does anyone know how I could best tackle this problem? The data is there, it just seems the collection of the comments doesn't gets updated.
Edit: I can make the Post model bind it's change:comments to itself, which updates the collection. However, I can't seem to find a solid way to get the original comments' JSON, since this.get('comments') returns the Comments collection.
Note: In my collection, I do parse the JSON to make it work with my API, with the following code:
parse: function(response) {
var response_array = [];
_.each(response, function(item) {
response_array.push(item);
});
return response_array;
}
This is because the JSON returned by my API returns an object with indexed keys (associative array) instead of a native JSON array.
{
"id" : "1",
"title" : "post title",
"comments" : {
"2" : {
"id" : "2",
"description": "this should solve it"
},
"6" : {
"id" : "6",
"description": "this should solve it"
}
}
}
Thanks a bunch! Please ask any questions, I'm sure I've been vague somewhere!
The Backbone Relational model doesn't parse collections other then arrays, the JSON from my question didn't work. I changed the backend to return the comments in a proper array
{
"id" : "1",
"title" : "post title",
"comments" : [
{
"id" : "2",
"description": "this should solve it"
},
{
"id" : "6",
"description": "this should solve it"
}]
}
}
The RelationalModel doesn't respect the parse function that Backbone provides to parse your JSON before it moves on. With the backend returning "proper" JSON, the lazy loading works without any extra code.
You can also use the initialize method on your comment model, to simulate the parse method and define attributes with custom values like this (CoffeeScript):
initialize: (obj) ->
#attributes = obj.customKey

Categories

Resources