How to fetch data from json using Reactjs - reactjs

I know this is very basic. but i would appreciate if anyone can help me understanding on how to fetch data from json using React js.
I have just started to learn React so was just curious to know if there are any ways to fetch data from complex json using this.
I have tried to follow React Tutorial
I am trying to fetch data from 2nd level keys in a json. I was able to do that using Object.keys, but I am not sure what the issue is here when i am trying to apply it to my dataset. I am just unable to get anything when i try the commented dataset which is not that different from the other dataset. Can Object.keys be applied to datasets where there are more than one key? Can anyone please help?
Please check my fiddle
Here is my code
var SearchStock = React.createClass({
getInitialState: function() {
return {searchString: ''};
},
handleChange: function(e) {
this.setState({searchString: e.target.value});
},
render: function() {
var stocks = this.props.items, searchString = this.state.searchString.trim().toLowerCase();
if (searchString.length > 0) {
stocks = stocks.filter(function(l) {
// return l.name.toLowerCase().match(searchString);
return l[Object.keys(l)[0]]["name"].toLowerCase().match(searchString);
});
}
return <div >
< input type = "text" value = {this.state.searchString} onChange = {this.handleChange} placeholder = "Type here" / >
< ul >
{stocks.map(function(l) {
return <li > {l[Object.keys(l)[0]]["name"]} < /li>
// return <li > {l[Object.keys(l)[0]]["name"]} < /li>
})
}
< /ul>
< /div>;
}
});
// var stocks = [{"F": {"symbol": "F", "name": "Ford Motor", "bidPrice": 13.41, "askPrice": 13.36}}, {"GE": {"symbol": "GE", "name": "General Electric", "bidPrice": 32.33, "askPrice": 32.39}}, {"JNJ: {"symbol": "JNJ", "name": "Johnson \u0026 Johnson", "bidPrice": 121.0, "askPrice": 123.0,}}];
var stocks = [{"symbol": {"symbol": "F", "name": "Ford Motors"}, "name": "Ford Motor", "bidPrice": 13.41, "askPrice": 13.36}, {"symbol": {"symbol": "GE", "name": "General Electronics"}, "name": "General Electric", "bidPrice": 32.33, "askPrice": 32.39}, {"symbol": {"symbol": "JNJ", "name": "Johnson \u0026 Johnson"}, "name": "Johnson \u0026 Johnson", "bidPrice": 121.0, "askPrice": 123.0,}];
ReactDOM.render( < SearchStock items = {stocks} />,document.getElementById('container'));
My Aim is to build a simple single page app in which we can search data from json using the key.symbol, so i am adding another level to the data so that when i build my api i can just put it there using the symbol.
I would appreciate if anyone can help me out with this. Sorry for changing my question in the middle. And thanks for pointing me in the right direction.

implement that in the componentDidMount method of your Stock element.
Something like this:
var Stock = React.createClass({
...
render: function() {
...
},
componentDidMount: function() {
let url = 'myStockApi/' + this.props.symbol;
this.serverRequest = $.get(url, function(result) {
let quote = result;
this.setState({
quote
});
}.bind(this));
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
});
Check out the documentation here.

I was able to find my answer from here . I have update my post. Please check the code in my post.

Related

How to read objects and store into array

I made an http request and got back e.g the below json. I want to read the cars and the shoes objects into separate arrays at the time of the http request.
json
{
"id": 9,
"name": "Zlatan",
"cars": [
{
"type": "ford",
"year": "2019"
},
{
"type": "audi",
"year": "2017"
}
]
"shoes": [
{
"brand": "adidas",
"status": "old"
},
{
"brand": "timberland",
"status": "new"
}
]
}
comp.ts
cars = [];
shoes = [];
//......
getZlatan() {
return this.httpService.getInfo()
.subscribe( data => {
this.objZlatan = data; //this part holds the json obj above
this.cars ....//what to add here
this.shoes ....// here too.
} );
}
Or is there a cleaner way to load the arrays at http request?
Access the cars and shoes properties of the data with simple dot-notation. It might be ideal to check if the data returned is not null with if(condition here) and then perform your logic. If you have more objects and want to bring all cars and shoes under one array then you have to loop through.
getZlatan() {
return this.httpService.getInfo()
.subscribe(data => {
this.objZlatan = data;
this.cars = this.objZlatan.cars;
this.shoes = this.objZlatan.shoes;
});
}
Just use . and type names to access cars and shoes. Let me show an example:
return this.httpService.getInfo()
.subscribe( data => {
this.objZlatan = data; //this part holds the json obj above
this.cars = data.cars;
this.shoes =data.shoes;
} );

ReactJS ES6 array filtering

I'm trying to group data from an object to a multidimensional array
In the last three days I've tried multiple ways to get the result I want. Since I've no luck, probably because of my poor knowledge of ReactJS/ES6. I hope someone can explain how I can get this to work.
I think I'll have to use the map function. Within the map function, a filter function to get the unique companies and then a loop to add the table information.
The end result should be like this: https://wireframe.cc/No5uB7
The data I'd like to filter:
{
"viewings": [
{
"companyXXX": "company-XXX",
"time_start": "02/04/2019",
"time_end": "03/04/2019 11:59"
},
{
"companyXXX": "company-XXX",
"time_start": "14/04/2019",
"time_end": "15/04/2019 11:59"
},
{
"companyYYY": "company-YYY",
"rejection": 40,
"time_start": "14/04/2019",
"time_end": "15/04/2019 11:59"
}
]
}
The code I still have that isn't working
genData(data) {
const di = data.viewings;
let mps = [];
di.map(m => mps.push(m.company));
mps = Array.from(new Set(mps));
console.log( mps );
let mps = [];
di.map((m) =>
console.log( di.filter(mps => m.company) )
);
}
I might help if your input data was a bit more consistent, especially since you're trying to write m.company, which won't mean anything unless there is a company object in each viewing.
{
"viewings": [
{
"company": "company-XXX",
"time_start": "02/04/2019",
"time_end": "03/04/2019 11:59"
},
{
"company": "company-XXX",
"time_start": "14/04/2019",
"time_end": "15/04/2019 11:59"
},
{
"company": "company-YYY",
"time_start": "14/04/2019",
"time_end": "15/04/2019 11:59"
}
]
}
Then you can write:
var viewings = data.viewings.
var firstViewing = viewings[0];
var firstCompany = firstViewing.company;
var firstTimeStart = firstViewing.time_start;
// etc...
Your input data should be more structured to begin with.
Then you can log out each company name:
var viewings = data.viewings;
viewings.forEach(v => {
console.log(v.company);
});
You mention JSX in your question, but there's no JSX code. This appears to be an issue with your knowledge of JS rather than JSX.

Nesting storing and sorting in struct in angular

Ok, so I have a JSON file with lots of information that can be sorted many ways. The actual JSON is too large, but for a relevant example:
$myData =
{
"id":1,
"author_id":[17],
"date":"10/1/1996",
"title":"Article1"
},
{
"id":2,
"author_id":[16,17],
"date":"9/1/1996",
"title":"Article2"
},
{
"id":3,
"author_id":[16],
"date":"6/1/1996",
"title":"Article3"
};
I want to be able to sort this into a struct with the basic structure like:
$myDataByAuthor =
{"17" =
{
"id":1,
"date":"10/1/1996",
"title":"Article1"
},
{
"id":2,
"date":"9/1/1996",
"title":"Article2"
}
},
{"16" =
{
"id":3,
"date":"6/1/1996",
"title":"Article3"
};
{
"id":2,
"date":"9/1/1996",
"title":"Article2"
}
};
I know the syntax there is bad, but I'm not really sure how to lay this out which is why I'm asking.
The reason I want to do this is because I want to turn around and, using ng-repeat in my code be able to output something to effect of:
Author with id 16
6/1/1996 - Article3
9/1/1996 - Article2
Author with id 17
9/1/1996 - Article2
10/1/1996 - Article1
I'm just not seeing how to get this done.
Thanks!
You can certainly restructure it that way, and here is a fiddle and code of the function that would restructure it that way for you.
var table = {}
myData.forEach(function(element){
element.author_id.forEach(function(id){
table[id] = table[id] || []
table[id].push(element)
})
})
https://jsfiddle.net/q40yhhko/
Considering your data is:
$myData = [{ "id":1, "author_id":[17], "date":"10/1/1996", "title":"Article1"},
{"id":2, "author_id":[16,17], "date":"9/1/1996", "title":"Article2"},
{"id":3, "author_id":[16], "date":"6/1/1996", "title":"Article3" }];
To form the required JSON use below code
$scope.requiredJSON = {}; //FORMATED JSON DATA
angular.foreach($myData, function(value, index){
angular.foreach(value.author_id, function(innerVal, innerIndex){
$scope.requiredJSON[innerVal] = $scope.requiredJSON[innerVal] || [];
$scope.requiredJSON[innerVal].push({id: value.id, date: value.date, title: value.title});
})
});
Following is the output:
{17: [{"id":1, "date":"10/1/1996", "title":"Article1" },
{"id":2, "date":"9/1/1996", "title":"Article2" }],
16: [{"id":2, "date":"9/1/1996", "title":"Article2" }]};
https://jsfiddle.net/AmitParrikar/uzv2p72b/2/

Merge objects with different values using Angularjs or Underscore js

I'm trying to merge two objects into a single multidimensional object for use in Angularjs controller by the 'unique_id'. (Note I also have Underscore Js added in).
Object #1 example:
[
{ "unique_id": "001", "title": "Putting Green Challenge - Motion Depends on Force and Mass" },
{ "unique_id": "002", "title": "Molecules to Organisms: Frog Life Cycle" }
]
Object #2 example (has MANY more rows than object 1..):
[
{
"ab_id": "76153F02-29F3-11D8-95EA-951BF95D9AEF",
"unique_id": "001",
"title": "How Speed Relates to Energy",
"state": "NY",
"document_title": "Core Curriculum",
"grade_code": "K-4",
"grade_descr": "Elementary",
"state_id": "1.S2.3a",
"state_text": "Use appropriate \"inquiry and process skills\" to collect data"
},
{
"ab_id": "7980A762-29F3-11D8-BD14-861D7EA8D134",
"unique_id": "001",
"title": "How Speed Relates to Energy",
"state": "NY",
"document_title": "Core Curriculum",
"grade_code": "5-8",
"grade_descr": "Intermediate",
"state_id": "1.S3.2d",
"state_text": "formulate and defend explanations and conclusions as they relate to scientific phenomena"
}
]
My Controller:
abApp.controller("abEE", function(abService, $http, $scope, $q, _) {
var abApp = this;
$scope.abData = $http.get('/data/ab_activities.json', {
cache: false
});
$scope.eeData = $http.get('/activities/eedata', {
cache: false
});
$q.all([$scope.eeData, $scope.abData]).then(function(values) {
var val = ??? This is where I want to merge the objects into one big multidimensional object..
});
Here is the output of console.dir(values);
0 Object { data=[28], status=200, config={...}, more...}
1 Object { data=[743], status=200, config={...}, more...}
This is the desired output I'd like to try and get:
[
{ "unique_id": "001", "title": "Putting Green Challenge - Motion Depends on Force and Mass", "alignments": [{"ab_id": "76153F02-29F3-11D8-95EA-951BF95D9AEF","unique_id": "001","title": "How Speed Relates to Energy",...}, {"ab_id": "7980A762-29F3-11D8-BD14-861D7EA8D134", "unique_id": "001", "title": "How Speed Relates to Energy",...}]
]
Edit
after you updated the question, i created this plunker
hopes it's what you meant
To merge all objects by unique_id
var unions = {};
$q.all([$scope.eeData, $scope.abData]).then(function(values)
{
for (var i = 0; i< values.length; i++)
{
var value = values[i];
if (!unions[value.unique_id])
{
unions[value.unique_id] = {};
}
angular.extend(unions[value.unique_id], value);
}
});
// Do somthing with 'unions'
...
If you could switch to use lodash instead of underscore, it can be achieved like this:
var val = _.values(_.merge(_.indexBy(values[0].data, 'unique_id'), _.indexBy(values[1].data, 'unique_id')));
The underscore doesn't have _.merge(), you have to loop through each property without it.
I don't think angular or underscore have this kind of functionality. I would do something like the following pseudo-code:
tempObject = {}
for object in objectArray
if tempObject[object.unique_id] isnt undefined
tempObject[object.unique_id] = object
else angular.extend(tempObject[object.unique_id], object) // or the other way around depending on your preference
resultingArray = []
for object, key of tempObject
resultingArray.push(object)
You will have to run the for object in objectArray for both the returned arrays but that should work and is probably more efficient than most merge algorithms as at most it will loop through each returned arrays twice.

How to get a valid filtered model from a Backbone Collection?

I'm sure I make one of these Backbone newbie mistakes but after a hour of searching around I didn't found a solution.
Here's the problem: When I try to get a filtered model from my collection theres a type error "productCollection.getProductByName("M020012").toJSON is not a function".
But if I change the filter method to a simple "return this.at(0)" I get a valid model.
Why is that and what is the solution?
Here's the JSFiddle
var products = [{
"name": "M020013",
"gender": "M",
"pictures": [{
"picture": {}}]},
{
"name": "M020012",
"gender": "M",
"pictures": [{
"picture": {}}]},
{
"name": "M020011",
"gender": "M",
"pictures": [{
"picture": {}}]}
];
var Product = Backbone.Model.extend({});
var ProductCollection = Backbone.Collection.extend({
model: Product,
getProductByName: function(productName) {
//return this.at(0);
return this.filter(
function(product) {
return product.get('name') === productName;
});
}
});
var productCollection = new ProductCollection();
productCollection.on('reset', function() {
console.log('reset');
console.log(productCollection.getProductByName('M020012'));
console.log(productCollection.getProductByName('M020012').toJSON());
});
productCollection.reset(products);
It's because filter returns an array of models. And an Array in javascript does not have a toJSON function.
Since you want to return a model instead of an array, then you can use the find in place of filter. The find method returns the first model that matches the criteria
Here's what the code would look like:
getProductByName: function(productName) {
return this.find(function(production) {
return production.get('name') === productName;
});
}

Resources