Related
I'm having problems retrieving my data, I think because there are spaces in the JSON between the words. What is a good way of dealing with that so that I can use the JSON properly? I'm trying to loop through each of the games and get the id out of them but I think the "NCAA Division I" is messing it up.
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
class GameList extends Component {
state = { games: [] };
componentWillMount() {
axios.get('https://sportstakehouse.islandshore.net/dbdata/gameday/division')
.then(response => this.setState({games: response.data}));
}
renderGames() {
return this.state.games.map(game => <Text>{game.id}</Text>)
}
render() {
return (
<View>
<Text>{this.renderGames}</Text>
</View>
);
}
}
export default GameList;
That's my react code, I'm trying to get each game id out of this:
{
NCAA Division I: [
{
id: "4966",
api_id: "0a647d19-7150-4c66-92f1-f4f3fe9cd45d",
status: "scheduled",
scheduled: "2018-02-22 18:00:00",
conference_game: true,
game_time_date: "2018-02-22",
game_time_hour: "6:00pm",
home_team: {
id: "647",
api-id: "c851131a-5ecd-4670-81bc-b40f4837dd65",
name: "Owls",
alias: "FAU",
market: "Florida Atlantic",
conference-id: "74",
color-primary: "004B85",
color-secondary: "bb2f4c"
},
away_team: {
id: "646",
api-id: "bb384635-c3a0-459a-8f13-fcd7177313e5",
name: "Owls",
alias: "RICE",
market: "Rice",
conference-id: "74",
color-primary: "003D7D",
color-secondary: "d1d5d8"
},
venue: "FAU Arena",
broadcast_network: "",
broadcast_internet: "",
home_team_conference: "Conference USA",
away_team_conference: "Conference USA",
home_team_division: "NCAA Division I",
away_team_division: "NCAA Division I",
total_points_bet: 0,
total_points_bet_on_hometeam: 0,
total_points_bet_on_awayteam: 0,
featured: true
},
{
id: "4967",
api_id: "3c00c7ad-eaa7-4611-ba38-306e6d358332",
status: "scheduled",
scheduled: "2018-02-22 18:00:00",
conference_game: true,
game_time_date: "2018-02-22",
game_time_hour: "6:00pm",
home_team: {
id: "638",
api-id: "58d8baa3-7624-4b21-a47f-a23df2bf8859",
name: "Thundering Herd",
alias: "MRSH",
market: "Marshall",
conference-id: "74",
color-primary: "186329",
color-secondary: "be854c"
},
away_team: {
id: "648",
api-id: "ce967953-5c50-4220-87b2-99acb9606e84",
name: "Monarchs",
alias: "ODU",
market: "Old Dominion",
conference-id: "74",
color-primary: "00507d",
color-secondary: "a1d2f1"
},
venue: "Cam Henderson Center",
broadcast_network: "STADIUM",
broadcast_internet: "",
home_team_conference: "Conference USA",
away_team_conference: "Conference USA",
home_team_division: "NCAA Division I",
away_team_division: "NCAA Division I",
total_points_bet: 0,
total_points_bet_on_hometeam: 0,
total_points_bet_on_awayteam: 0,
featured: false
},
Yes you're are correct, the response you have given is not valid JSON. For many reasons not just that you have spaces in your keys.
To fix this you will need to edit where you are generating the data from, namely you will need to make the response valid:
{
"NCAA Division I": [
{
"id: "4966",
"api_id": "0a647d19-7150-4c66-92f1-f4f3fe9cd45d",
"status": "scheduled",
"scheduled": "2018-02-22 18:00:00",
"conference_game": true,
"game_time_date": "2018-02-22",
"game_time_hour": "6:00pm",
"home_team": {
"id": "647",
"api-id": "c851131a-5ecd-4670-81bc-b40f4837dd65",
"name": "Owls",
"alias": "FAU",
"market": "Florida Atlantic",
"conference-id": "74",
"color-primary": "004B85",
"color-secondary": "bb2f4c"
......
}
}
However, having spaces in an object (not JSON) is perfectly valid as your keys would just be strings so:
const data = {
'NCAA DIVISION I': []
}
Would be valid and you could interact with this data perfectly easily. Doing maps, filters etc
[Edit]
I just realised you haven't set a constructor on your class, this means you have no internal state:
class GameList extends Component {
construtor(props){
super(props);
this.state = {};
}
....
}
The problem is you're trying to map over an object, it's not an array. If you don't need the key, then you can set this.state.games to the values of what's being returned.
axios.get('https://sportstakehouse.islandshore.net/dbdata/gameday/division')
.then(response => this.setState({ games: Object.values(response.data) }));
I've been trying to import a local JSON file into my react components state for a while now and no matter how much i google and try - i cant seem to get it to work. Here is my json file:
{
"products": [
{"id": 1, "category": "paint", "name": "clowd", "type": "matt emulsion", "stocked": true, "size": "100x130", "thumbnail": "23-sm.png", "previewImg": "23.png"},
{"id": 2, "category": "paint", "name": "dålig sikt", "type": "matt emulsion/olja/akryl", "stocked": true, "size": "100x130", "thumbnail": "24-sm.png", "previewImg": "24.png"},
{"id": 25, "category": "print", "name": "MIMI | 2nd edition", "type": "akvarellppr, 70x100", "limited": "30", "available": "28", "price": "3,000", "stocked": true, "thumbnail": "mimisecond-sm.jpg", "previewImg": "mimisecond.jpg"},
{"id": 26, "category": "print", "name": "max", "type": "uppspänd canvas, 95x120", "limited": "30", "available": "28", "price": "7,000", "stocked": true, "thumbnail": "max-sm.jpg", "previewImg": "max.jpg"},
{"id": 38, "category": "places", "stocked": true, "desc": "Vernisage Strössel # Linnégatan, sthlm 2015", "thumbnail": "17.png", "previewImg": "17.png"},
{"id": 39, "category": "places", "stocked": true, "desc": "Max # Nybergsgatan, sthlm 2016", "thumbnail": "26.png", "previewImg": "26.png"}
]
}
Here is my react component:
import React, { Component } from 'react';
import data from 'data.json';
console.log(data);
// Component import
import Menu from './components/menu';
import Footer from './components/footer';
import ProductContainer from './components/productContainer';
import CategoryContainer from './components/categoryContainer';
class Archive extends React.Component {
constructor(props){
super(props);
this.state = {
products: data,
category: ""
};
this.filterHandler = this.filterHandler.bind(this);
}
// Set component state to the currently clicked "cat" (CategoryItem)
filterHandler(tag){
this.setState({
category: tag
})
}
render() {
// 1. Render CategoryContainer with props products and filterHandler function to show all uniqe CategoryItems and filter products based on category
// 2. Render ProductContainer based on category. If this.state.category.length is true - filter "prod" & where prod.categories is same type and name as this.state.category : else render all this.state.categories that matches "paint".
return (
<div>
<Menu />
<div className="archive-container">
<div className="archive-wrapper">
<CategoryContainer
filterHandler={this.filterHandler}
products={this.state.products}
/>
<br/><br/>
<ProductContainer
products={this.state.category.length
? this.state.products.filter((prod) => prod.category === this.state.category)
: this.state.products.filter((prod) => prod.category === 'paint')
}
/>
</div>
</div>
<Footer />
</div>
);
};
};
export default Archive;
Here is my webpack2 file:
// DEVELOPMENT
const webpack = require('webpack');
const path = require('path');
const entry = [
'webpack-dev-server/client?http://localhost:8080', // bundle the client for webpack-dev-server and connect to the provided endpoint
'webpack/hot/only-dev-server', // bundle the client for hot reloading only- means to only hot reload for successful updates
'./app.js'
]
const output = {
path: path.join(__dirname, 'dist'),
publicPath: '/dist',
filename: 'bundle.min.js'
}
const plugins = [
new webpack.HotModuleReplacementPlugin(), // enable HMR globally
new webpack.NamedModulesPlugin() // prints more readable module names in the browser console on HMR updates
]
const config = {
context: path.join(__dirname, 'src'),
entry: entry,
output: output,
devtool: "inline-source-map",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: path.join(__dirname, 'src'),
use: {
loader: "babel-loader"
}
},
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: { limit: 10000, name: './images/[name].[ext]' }
}]
},
{
test: /\.(sass|scss)$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}
]
},
plugins: plugins,
externals: {
jquery: 'jQuery'
}
}
module.exports = config
I get the error:
If I change the json file to a javascript object and input it directly into the constructor:
constructor(props){
super(props);
this.state = {
products: [
{id: 1, category: 'paint', name: 'clowd', type: 'matt emulsion', stocked: true, size: '100x130', thumbnail: '23-sm.png', previewImg: "23.png"},
{id: 2, category: 'paint', name: 'dålig sikt', type: 'matt emulsion/olja/akryl', stocked: true, size: '100x130', thumbnail: '24-sm.png', previewImg: "24.png"},
{id: 3, category: 'paint', name: 'dålig sikt', type: 'matt emulsion/olja/akryl', stocked: true, size: '100x130', thumbnail: '25-sm.png', previewImg: "25.png"},
{id: 4, category: 'paint', name: 'pink', type: 'matt emulsion', stocked: true, size: '100x130', thumbnail: '1-sm.png', previewImg: "1.png"},
{id: 5, category: 'paint', name: 'pink', type: 'matt emulsion', stocked: true, size: '100x130', thumbnail: '27-sm.png', previewImg: "27.png"},
{id: 6, category: 'paint', name: 'pinks', type: 'matt emulsion', stocked: true, size: '100x130', thumbnail: '2-sm.png', previewImg: "2.png"}
],
category: ""
}
this.filterHandler = this.filterHandler.bind(this);
}
Then it works fine. But I want it in a separate json file so it wont be bundled and so it will be easier for client to add items to the list.
Maybe there is a smarter way to do this, I'm new to react and webpack and are hoping to learn .. Greatful for any form of input. Thank you!
(if someone came to fix this... in comments of question are fixes to common mistakes while importing json file in webpack 2)
Your Archive.state looks like:
{
products: { products: [ (your rest of array) ] },
category: ""
}
Your error is
this.state = {
products: data,
category: ""
};
Should be:
this.state = {
products: data.products,
category: ""
};
I am having trouble getting my API json results to be pushed into the Ember Data object model array. I was previously using getJSON on my route however I now need to be able to filter the data on multiple properties and Ember Data provides built in methods for that...if I could get it work that is. I'm pretty new to this so I am probably missing something terribly obvious. Please let me know if I am missing any code to assist. When I look at the promises, it shows them fulfilled when pulling the data from the API but then it rejects when trying to query the local data store for records (shows null) which I believe means my data isn't getting added to the store in the first place. I would provide a JSBin but our api uses CORS and I can't get the JSbin origin to authenticate.
On the route I have tried the following. Both throw different errors:
return this.store.find('restaurant');
//returns error: Error while processing route: casualdining
//Array.prototype.map: 'this' is null or undefined.
return DineSection.Restaurant.find();
//Error while processing route: casualdining
//Object doesn't support property or method 'find'
The Application Code:
DineSection = Ember.Application.create({
rootElement: "#dinesection-app"
});
DineSection.Router.map(function () {
this.resource("casualdining");
this.resource("restaurant", { path: "/:id" });
});
DineSection.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'https://api.lakecountyfl.gov',
namespace: 'api/TourismListings',
pathForType: function (type) {
return "GetRestaurants";
}
});
DineSection.ApplicationStore = DS.Store.extend({
adapter: 'DineSection.ApplicationAdapter'
});
//SERIALIZE OUR JSON DATA FROM THE API into something ember data can use
DineSection.ApplicationSerializer = DS.RESTSerializer.extend({
normalizePayload: function (type, payload) {
return { restaurant: payload }
}
});
DineSection.Restaurant = DS.Model.extend({
name: DS.attr('string'),
address: DS.attr('string'),
city: DS.attr('string'),
zip: DS.attr('string'),
phone: DS.attr('string'),
website: DS.attr('string'),
facebook: DS.attr('string'),
flickr: DS.attr('string'),
hasphoto: DS.attr('boolean', {defaultValue: false}),
outdoordining: DS.attr('boolean', { defaultValue: false }),
breakfastprice: DS.attr('string'),
lunchprice: DS.attr('string'),
dinnerprice: DS.attr('string'),
description: DS.attr('string'),
primarycategoryname: DS.attr('string'),
primarycategoryslug: DS.attr('string'),
primarysubcategoryname: DS.attr('string'),
primarysubcategoryslug: DS.attr('string'),
foodtype: DS.attr('string'),
foodtypeid: DS.attr('number'),
ranking: DS.attr('number'),
region1: DS.attr('boolean', { defaultValue: false }),
region2: DS.attr('boolean', { defaultValue: false }),
region3: DS.attr('boolean', { defaultValue: false }),
region4: DS.attr('boolean', { defaultValue: false })
});
DineSection.CasualdiningRoute = Ember.Route.extend({
model: function () {
//return Ember.$.getJSON("https://devapi.lakecountyfl.gov/api/TourismListings/GetRestaurants");
return this.store.find('restaurant');
//return DineSection.Restaurant.find();
}
});
My JSON response looks like this (abbreviated to two records for simplicity):
[{
"$id": "1",
"id": 1212,
"name": "Al's Landing",
"address": "111 W. Ruby St.",
"city": "Tavares",
"zip": "32778",
"phone": "352-555-8585",
"website": "http://www.alslanding.com",
"facebook": "https://www.facebook.com/pages/ALS-landing/110275062350544",
"flickr": null,
"hasphoto": true,
"outdoordining": true,
"breakfastprice": "N/A",
"lunchprice": "$10-$20",
"dinnerprice": "$10-$20",
"description": "A casual dining atmosphere with an indoor/ outdoor bar and plenty of outdoor lakefront seating.",
"primarycategoryname": "Dining",
"primarycategoryslug": "dining",
"primarysubcategoryname": "Casual Dining",
"primarysubcategoryslug": "casualdining",
"foodtype": "American",
"foodtypeid": 13,
"ranking": 3,
"region1": false,
"region2": false,
"region3": true,
"region4": false
},
{
"$id": "2",
"id": 1026,
"name": "#1 Wok",
"address": "1080 E. Highway 50",
"city": "Clermont",
"zip": "34711",
"phone": "352-555-2346",
"website": "",
"facebook": "",
"flickr": "",
"hasphoto": false,
"outdoordining": false,
"breakfastprice": "N/A",
"lunchprice": "Less than $10",
"dinnerprice": "Less than $10",
"description": "",
"primarycategoryname": "Dining",
"primarycategoryslug": "dining",
"primarysubcategoryname": "Casual Dining",
"primarysubcategoryslug": "casualdining",
"foodtype": "Asian",
"foodtypeid": 1,
"ranking": 1,
"region1": false,
"region2": false,
"region3": false,
"region4": true
}
]
I think you need a 'root' key in your JSON like follows:
[ restaurants: {
My Json response is like this
{
"object": {
"assignments": [
{
"assignmentId": 14706368,
"sectionId": 0,
"assignmentType": "FILEATTACH",
"assignmentTitle": "file attachment A",
"assignmentStartDate": "01/01/1900",
"assignmentStartTime": "01:00AM",
"assignmentDueDate": "01/01/2100",
"assignmentDueTime": "01:00AM",
"isMarathonChain": "No",
"assignmentTimeLimit": 0,
"assignmentTimeRemaining": "0",
"marathonAssignmentStatus": "MARATHON_NOT_ASSOCIATED",
"showAssignmentAttemptsAndPasswordDetails": false,
"assignmentAttemptsTaken": 0,
"assignmentAttemptsAllowed": "1",
"showPasswordForm": false,
"isStartAssignment": true,
"isResumeAssignment": false,
"isSubmitAssignment": false,
"passwordRequired": false,
"isConvertToGeniusEnabled": false,
"draftNumber": 0,
"studentExceptionExistsForDueDate": false,
"isPastUploadDate": false,
"showMarathonPrerequisiteInfo": false
}
],
"sections": [
{
"sectionId": 241409387,
"courseId": 241409386,
"sectionName": "Section01"
}
],
"courses": [
{
"courseId": 241409386,
"courseName": "Tricon.Connect_01",
"showDiscipline": false
}
],
"users": [
{
"userId": 1000321061,
"firstName": "Ragu �������&^&",
"lastName": "+##)()XYZ �^^������",
"userType": "S"
}
],
"returnLMS": [
{
"returnUrl": "bb"
}
]
}
}
My data model is like this
var attr = DS.attr;
App.About = DS.Model.extend({
object: DS.hasMany('object')
});
App.Object = DS.Model.extend({
assignments: DS.hasMany('assignments'),
sections: DS.hasMany('sections'),
courses: DS.hasMany('courses'),
users: DS.hasMany('users'),
returnLMS: DS.hasMany('returnLMS')
});
App.Assignments = DS.Model.extend({
assignmentId: attr('number'),
sectionId:attr('number'),
assignmentType:attr('string'),
assignmentTitle:attr('string'),
assignmentStartDate:attr('string'),
assignmentStartTime:attr('string'),
assignmentDueDate:attr('string'),
assignmentDueTime:attr('string'),
isMarathonChain:attr('boolean'),
assignmentTimeLimit:attr('number'),
assignmentTimeRemaining:attr('number'),
marathonAssignmentStatus:attr('string'),
showAssignmentAttemptsAndPasswordDetails:attr('boolean'),
assignmentAttemptsTaken:attr('number'),
assignmentAttemptsAllowed:attr('number'),
showPasswordForm:attr('boolean'),
isStartAssignment:attr('boolean'),
isResumeAssignment:attr('boolean'),
isSubmitAssignment:attr('boolean'),
passwordRequired:attr('boolean'),
isConvertToGeniusEnabled:attr('boolean'),
draftNumber:attr('number'),
studentExceptionExistsForDueDate:attr('boolean'),
isPastUploadDate:attr('boolean'),
showMarathonPrerequisiteInfo:attr('boolean')
});
App.Sections = DS.Model.extend({
sectionId: attr('number'),
courseId: attr('number'),
sectionName: attr('string')
});
App.Courses = DS.Model.extend({
courseId: attr('number'),
courseName: attr('string'),
showDiscipline: attr('boolean')
});
App.Users = DS.Model.extend({
userId: attr('number'),
firstName: attr('string'),
lastName: attr('string'),
userType:attr('string')
});
App.ReturnLMS = DS.Model.extend({
returnUrl: attr('string')
});
In this App.About is my route name so I have created object inside this and rest of it as follows.
No i am getting my response from restadapter but somehow it is not matching it with my model format and my model object show empty.
Take a look at the JSON conventions Ember Data is expecting.
You can also input your models into a neat tool called the ember-data-model-maker, and see what the server responses should be.
If you don't have control over your server responses, you'll need to extend DS.RESTAdapter to manipulate your JSON to get it into the form Ember Data expects.
I've started creating a Sencha Touch 2 app that has two models defined, Change and Configuration. A Change belongsTo a Configuration. Both of the models also have a store setup. On the Changes store I have a proxy setup to request data that comes back in JSON format. The JSON data has a Change with a nested configuration. The Change loads just fine but when I try and get the associated Configuration from the Change instance it isn't working.
I've defined the models like this:
Change model:
Ext.define('Changes.model.Change', {
extend: 'Ext.data.Model',
xtype: 'changemodel',
config: {
fields: [
{name:'id', type:'int'},
{name:'changeId', type:'string'},
{name:'briefDescription', type:'string'},
{name:'configuration_id', type:'int'}
],
associations: [{
type:'belongsTo',
model:'Changes.model.Configuration',
primaryKey: 'id',
foreignKey: 'configuration_id',
associationKey: 'configurations'
}],
},
});
Configuration Model:
Ext.define('Changes.model.Configuration', {
extend: 'Ext.data.Model',
xtype: 'configurationmodel',
config: {
fields: [
{ name: 'id', type: 'int'},
{ name: 'longName', type: 'string' },
{ name: 'ciName', type: 'string' },
],
hasMany: {model: 'Change', name: 'changes'}
}
});
Each model has a store.
Changes store:
Ext.define('Changes.store.Changes', {
extend: 'Ext.data.Store',
requires: 'Changes.model.Change',
config: {
model: 'Changes.model.Change',
proxy: {
type: 'ajax',
url: 'services/changes.php',
reader: {
type: 'json',
rootProperty: 'changes'
}
},
sorters: [{ property: 'briefDescription', direction: 'ASC'}],
}
});
Configurations store:
Ext.define('Changes.store.Configurations', {
extend: 'Ext.data.Store',
requires: ['Ext.data.proxy.LocalStorage'],
config: {
model: 'Changes.model.Configuration',
grouper: {
sortProperty: "ciName",
direction: "DESC",
groupFn: function (record) {
return record.get('ciName')[0];
}
},
proxy: {
type: 'ajax',
url: 'services/configurationItems.php',
reader: {
type: 'json',
rootProperty: 'configurationItems'
}
}
}
});
My JSON that is being returned from services/changes.php looks like this:
{
"success": true,
"changes": [
{
"id": 1,
"changeId": "XYZ19178263",
"briefDescription": "Loaded from Proxy",
"configuration_id": 3,
"configurations": [
{
"id": "3",
"longName": "999-99_-_windows_7_desktop.Computer.Windows",
"ciName": "999-99_-_windows_7_desktop"
}
]
}
]
}
In the browser's console I can issue the following commands:
Changes.myStore = Ext.getStore('Changes');
Changes.myStore.load();
Changes.record = Changes.myStore.findRecord('id', '1');
Changes.record.getAssociatedData()
The last command will return an object with a Configuration object inside but all of the field values show null except for id which appears to be set to a random value:
Object
Configuration: Object
ciName: null
id: "ext-record-11"
longName: null
Can anyone see why the nested Configuration instance in my JSON isn't being saved? And should the nested Configuration instance in the JSON be added to the Configurations store automatically?
Sadly this just doesn't work. Appears to be a shortcoming of the framework. You can't load and save associated (aggregated/nested) objects. You need to flatten out your structure and then associate objects in code yourself.
So for example... your JSON would then be...
{
"success": true,
"changes": [
{
"id": 1,
"changeId": "XYZ19178263",
"briefDescription": "Loaded from Proxy"
}
]
}
And a second JSON file/response as follows:
{
"success": true,
"configurations": [
{
"id": "3",
"longName": "999-99_-_windows_7_desktop.Computer.Windows",
"ciName": "999-99_-_windows_7_desktop",
"change_id": 1
}
]
}
Tinashe's answer is not correct. You can certainly get nested models.
You have your associations backward with respect to your JSON, however.
"changes": [
{
"id": 1,
"changeId": "XYZ19178263",
"briefDescription": "Loaded from Proxy",
"configuration_id": 3,
"configurations": [
{
"id": "3",
"longName": "999-99_-_windows_7_desktop.Computer.Windows",
"ciName": "999-99_-_windows_7_desktop"
}
]
}
]
means a change hasMany configurations, but you are saying it belongsTo it. This is the correct JSON:
"changes": [
{
"id": 1,
"changeId": "XYZ19178263",
"briefDescription": "Loaded from Proxy",
"configuration_id": 3,
"configuration":
{
"id": "3",
"longName": "999-99_-_windows_7_desktop.Computer.Windows",
"ciName": "999-99_-_windows_7_desktop"
}
}
]
Either way, you need to set getterName (setterName if you like too) on the relationship:
associations: [{
type:'belongsTo',
model:'Changes.model.Configuration',
primaryKey: 'id',
foreignKey: 'configuration_id',
associationKey: 'configuration',
getterName:'getConfiguration'
}]
Then after the store loads, you can call myChangeModel.getConfiguration();