Getting key and value from JSON with angular2 - json

I am looking for best solution how to work with JSON in my angular2 app.
My JSON is:
{
"rightUpperLogoId": {
"id": 100000,
"value": ""
},
"navbarBackgroundColorIdCss": {
"id": 100001,
"value": ""
},
"backgroundColorIdCss": {
"id": 100002,
"value": ""
},
"translationIdFrom": {
"value": "90000"
},
"translationIdTo": {
"value": "90055"
}
}
This JSON is something like configuration file for UI of app. In my application, I want to get id from rightUpperLogoId, it is 100000. With this id I need to do GET task on my backend REST api and the returned value I would like to set to value. Thank you

You could leverage Rx operators like the flatMap one with Observable.forkJoin / Observable.of.
Here is a sample:
this.http.get('config.json')
.map(res => res.json())
.flatMap(config => {
return Observable.forkJoin(
Observable.of(config),
// For example for the request. You can build the
// request like you want
this.http.get(
`http://.../${config.rightUpperLogoId.id}`)
);
})
.map(res => {
let config = res[0];
let rightUpperLogoIdValue = res[1].json();
config.rightUpperLogoId.value = rightUpperLogoIdValue;
return config;
})
.subcribe(config => {
// handle the config object
});
This article could give you more hints (section "Aggregating data"):
http://restlet.com/blog/2016/04/12/interacting-efficiently-with-a-restful-service-with-angular2-and-rxjs-part-2/

Related

Replacement in a json array - Angular

I am trying to replace an object in my json web server array : If an object with a similar id is already in the json array.
This is my json array :
{
"history": [
{
"id": 4,
"SNS": "BockeSinoJutsu-SNS",
"title": "BockeSinoJutsu-title",
"DMC": "BockeSinoJutsu-DMC",
"date": "June 15 2022"
},
{
"id": 1,
"SNS": "Rasengan-SNS",
"title": "Rasengan-title",
"DMC": "Rasengan-DMC",
"date": "2022-06-18T17:43:59.708Z"
}
]
}
And this is the json file I am comparing it to :
{
"content":[
{
"id":1,
"SNS":"Rasengan-SNS",
"title":"Rasengan-title",
"DMC":"Rasengan-DMC"
},
{
"id":2,
"SNS":"Mangekyu-SNS",
"title":"Mangekyu-title",
"DMC":"Mangekyu-DMC"
},
{
"id":3,
"SNS":"Chidori-SNS",
"title":"Chidori-title",
"DMC":"Chidori-DMC"
}
]
}
This is what I have tried :
onAddHistory(history:History){
history.date = new Date();
console.log(history.SNS);
this.historyService.getHistory().subscribe(
(response:History[])=>{
this.ExistingHistory=response.filter(x => x.id === history.id);
console.log(this.ExistingHistory);
if(this.ExistingHistory.length !== 0){
this.onDeleteHistory(this.ExistingHistory.id);
this.historyService.addHistory(history).subscribe(
()=>{console.log("Success !");
this.Histories$=this.historyService.getHistory();},
()=>{console.log("error")}
);
}else{
this.historyService.addHistory(history).subscribe(
()=>{console.log("Success !");
this.Histories$=this.historyService.getHistory();},
()=>{console.log("error")}
);
}
}
);
}
But I get the following error, saying that it cannot read id of undefined :
The error basically says that ExistingHistory.id is undefined
JavaScript's Array.filter() returns a filtered array. You can't access this.ExistingHistory.id because this.ExistingHistory is an array, you would have to access it like so: this.ExistingHistory[0].id
If you want to get one value only then you should use Array.find():
this.ExistingHistory = response.find(x => x.id === history.id);
If there is a chance there is more than one duplicate, then you should use a .forEach loop:
this.ExistingHistory.forEach((x) => {
this.onDeleteHistory(x.id);
}
Do be warned however that you have a ton of nested subscriptions in that method, which is generally considered bad practice. I advise you to look into RXJS

Why are there data types included in this JSON response?

I'm consuming an API via React-Native, and data-type strings are being included in the JSON response as such:
{"volumeInfo": Object {
"allowAnonLogging": false,
"authors": Array [
"Tim Mathers",
],
"canonicalVolumeLink": "https://market.android.com/details?id=book-ZzOPDwAAQBAJ",
"categories": Array [
"Sports & Recreation",
]}
Notice the "Object" and "Array" type strings included in the response.
When I curl the same exact endpoint from my CLI, I get correctly formatted JSON as such:
{"volumeInfo": {
"title": "Baseball",
"subtitle": "America's Diamond Mind, 1919-1941",
"authors": [
"Richard C. Crepeau"
],
"publisher": "U of Nebraska Press",
"publishedDate": "2000"}
The data from curl is not only coming back in the correct format, but also in a completely different order than my application. This leads me to believe that my implementation is the cause. See code below
Action
export function searchBooks(book)
{
const url = `${BASE_URL}q=${book}&filter=free-ebooks&key=${API_KEY}`;
return dispatch => {
dispatch(getData());
fetch(url)
.then(blob => blob.json())
.then(data => {
console.log(data)
dispatch(getDataSuccess(data))
})
.catch(e => {
console.log(e);
dispatch(getDataFailure(e.message))
});
}
}
Reducer
const initialState = {
payload:[],
fetching: false,
error: false
}
export default function(state=initialState, action){
switch (action.type){
case FETCHING_DATA: return {payload:[], fetching: true, ...state}
case FETCH_SUCCESS: return {payload:[action, ...state]}
case ERROR: return {payload:[], error: true, ...state}
}
return state;
}
Thank you for any clarification as to why data types are included in my JSON, and how my implementation could be the reason.

get json value object from mongodb

I have formData node that has dynamic jsonObject value in mongodb
{
"_id": {
"$oid": "5a71fea0f36d2848ae4f8f0a"
},
"formData": {
"pages": [
{
"name": "page1",
"questions": [
{
"type": "comment",
"name": "about",
"title": "Please tell us about your main requirements "
}
]
}
]
},
"editorId": "59678e58f36d2842f777bc48",
"datetimeSubmit": "2018/01/15"
}
I write a node API to fetch the data from mongodb, it only display ids, editorI and datetimesubmit nodes, but it ignores the formData(jsondata) field.
const Model = require('./myModel');
module.exports = {
getData: function (callback) {
Model.find({}, (err, jsonObj) => {
callback(null, {
data: jsonObj
})
})
}
}
looks like the model.find() doesn't return jsonObject value?
thanks
got my own question fixed, basically, i should also define the data type as JSON in schema, otherwise, will be ignored.

How to remove Task json properties in Nancy.Response.AsJson

I've made one of my API endpoints and inner logic asynchronous and when previously I've used Response.AsJson(Foo.bar()) , it would return the json representation normally, but now I see this appended to it:
{
"result": [
{
"id": "59d680cc734d1d08b4e6c89c",
"properties": {
"name": "value"
}
}
],
"id": 3,
"exception": null,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"isCompletedSuccessfully": true,
"creationOptions": 0,
"asyncState": null,
"isFaulted": false
}
But I want it to be like this:
"id": "59d680cc734d1d08b4e6c89c",
"properties": {
"name": "value"
}
As I understand, it's because I've wrapped my object in a Task , but I can't figure out, how with Nancy framework, which I use the Response.AsJson, to make it so the properties are excluded. I can obviously omit the Response.AsJson of the returned object, but then response is no longer Json if requesting through web-browser for example.
For further example
NancyModule for routing API:
public ItemCatalogModule(IItemCatalog itemCatalog) : base("/itemCatalog")
{
Get("/fetch/{id}", async parameters =>
{
var id = (string) parameters.id;
var response = await Response.AsJson(itemCatalog.GetItem(id));
return response;
});
}
How the interface looks like of ItemCatalog:
public interface IItemCatalog
{
Task<Item> GetItem(string id);
}
You shoud do this :
public ItemCatalogModule(IItemCatalog itemCatalog) : base("/itemCatalog")
{
Get("/fetch/{id}", async parameters =>
{
var id = (string) parameters.id;
return Response.AsJson(await itemCatalog.GetItem(id));
});
}

Nested JSON with objects and arrays, find value

Im building a React app and I have a quite complex JSON file where I need to find and output certain values of an object in an array.
Im trying to output all my people from my JSON, they look something like this:
people: [
{
"id": 1,
"email": "Sincere#april.biz",
"address": [
{
"street": "Kulas Light",
"type": "house",
"attribute": {
"sketch": "sketch.jpg",
"photo": "photo.jpg"
}
},
{
"street": "Lorem Ipsum",
"type": "apartment",
"attribute": {
"sketch": "sketch.jpg",
"photo": "photo.jpg"
}
}
]
}
]
I have no problem to output the email, doing it like so:
var App = React.createClass({
getInitialState: function () {
return {
results: {}
}
},
componentDidMount() {
fetch(REQUEST_URL) // fetch from API, returns JSON
.then(res => res.json())
.then(data => {this.setState(
{ results: data.people}
);
})
},
renderResult : function(key){
return <Result key={key} index={key} details={this.state.results[key]}/>
},
render : function() {
return (
<ul>
{Object.keys(this.state.results).map(this.renderResult)}
</ul>
)
}
});
var Result = React.createClass({
render : function() {
return (
<li>
{this.props.details.email}
<img src="{this.props.details.address.type=house.attribute.photo}"/>
</li>
)
}
});
ReactDOM.render(App, document.querySelector('#app'));
However, now I need to output "photo" but only for "type": "house". I tried this but no luck, well aware that this is way off. Im quite new to handling JSON data and React and Google hasn't helped me even after a few hours of trying to solve this.
The .address property isn't an object but an array of objects so
.type is not available directly on .address:
this.state.results.people.address.type
// .type property doesn't exist on array
Solution:
You can use Array.prototype.filter on .address to obtain an array of objects that have a property type whose value is "house":
var houseAddresses = this.state.results.people.address.filter(function(value){
return value.type === "house";
});
Here, houseAddress will be an array of objects whose type value is 'house".
You can then loop through the array to create the relevant JSX using for, Array#forEach or Array#map. The following example uses Array#map:
const houseImgTags = houseAddresses.map(function(house, index){
return (
<img
src={house.attribute.photo}
key={'house'+index}
/>
);
});
(A key was added here in case there are more than one instance of a house object)
You can simply write.
<img src={this.states.results.address.type==="house"?house.attribute.photo : otherwise_photo}/>
Basically this would compare address.type is house or not,then return the result corresponded.