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: {
Related
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'm programming a function in order to update users' info. I did it and it works fine however it doesn't work when I want to use custom schemas. I checked the reference but it showed an error "Invalid Input: [employmentData] "
function directoryUpdate(userId, userDept, userLocation, userPhone,userTitle) {
var userId = 'devtest#pruebatest.com',userDept='D003', userLocation='L003';
var userTitle='T003';
var update = {
ims:
[{
type: "work",
protocol: "gtalk",
im: "liz_im#talk.example.com",
primary: true
}],
emails: [
{
address: "liz#example.com",
type: "home",
customType: "",
primary: true
}
],
addresses:
[{
type: "home",
customType: "",
streetAddress: "1600 Amphitheatre Parkway",
locality: "Mountain View",
region: "CA",
postalCode: "94043"
}
],
organizations:
[{
name: "Next Step",
title: userTitle,
primary: true,
type: "work",
department: userDept,
location: userLocation
}],
customSchemas: {
employmentData: {
employeeNumber: "123456789",
jobFamily: "Engineering",
location: "Atlanta",
jobLevel: 8,
projects: [
{ value: "GeneGnome", customType: "development" },
{ value: "Panopticon", customType: "support" }
]
}
}
};
update = AdminDirectory.Users.patch(update, userId);
Logger.log('User %s updated with result %s.', userId, update)
return true;
}
What's the error?
Greetings, Thanks in advance.
The employmentData field is inside the "customSchemas" field. Custom schemas have to be defined before using them.
To create a Custom Schema you have to use the resource Schemas.insert.
After creating the schema with the correspondent fields and type of value (STRING, INT, ETC) your code should run without issues. I tried it and worked for me.
Also, after updating the user, when making the call to Users.get, you have to set the parameter "projection=full" in order to see these values in the response.
I'm trying to normalize some non conventional json data from server to be used in ember.
The json response looks like this
{
"pagingAndSorting": {
"pageSize": 2,
"ascending": false,
"pageNumber": 5
},
"list": [
{
"recommendedDosage": "400mg Tablets",
"active": true,
"name": "ANT-Norfloxacin",
"id": "FE102EDA-984A-41A3-B9C8-3E13B98A864A",
"identifiers": []
},
{
"recommendedDosage": "",
"active": true,
"name": "ANT-Penicillin Injection",
"id": "F8DE6184-0F91-4DA9-A611-2B78F4B85D25",
"identifiers": []
},
{
"recommendedDosage": "",
"active": true,
"name": "ANT-Spectinomycin",
"id": "73205995-0CF2-4744-A856-F74B81355661",
"identifiers": []
}],
"fullListSize": 574
}
I created the following models
in app/model/paging-and-sorting.js
import DS from 'ember-data';
export default DS.Model.extend({
pageNumber : DS.attr('number',{defaultValue: 0}),
pageSize : DS.attr('number',{defaultValue: 40}),
ascending : DS.attr('boolean', {defaultValue: false})
});
in app/models/medicine.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('String'),
identifiers: DS.attr(''),
active: DS.attr('Boolean',{defaultValue: true}),
id: DS.attr('String'),
recommendedDosage : DS.attr('String')
});
In app/models/medicine-list.js
import DS from 'ember-data';
export default DS.Model.extend({
pagingAndSorting: DS.belongsTo('paging-and-sorting'),
list: DS.hasMany('medicine'),
fullListSize: DS.attr('number')
});
In app/serializers/medicine-list.js i have
import DS from 'ember-data';
//For the embedded Ember model
export default DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
pagingAndSorting : { embedded: 'always' },
list: { embedded: 'always' }
}
});
But this does not seem to be working. I'm not seeing any error in the console, however when i inspect using ember data it seems like no data gets into the ember store.
Am i missing something obvious?
Does anyone have another solution/approach?
Thanks for your help!
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 have this question model:
App.Question = DS.Model.extend({
title: DS.attr('string'),
description: DS.attr('string'),
subjects: DS.hasMany('subject', {embedded: 'always')
});
App.Subject = DS.Model.extend({
description: DS.attr('string')
question: DS.belongsTo('question')
});
App.QuestionAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:3000'
});
App.QuestionSerializer = DS.RESTSerializer.extend({
primaryKey: '_id',
serializeId: function(id) {
return id.toString();
}
});
and this is my data sample:
{
"questions":
[{
"_OwnerId": "53e440b3b6d1de0b3cc12b44",
"__v": 0,
"_id": "53f03ac07295ef2b467551d9",
"description": "0987654321",
"subjects": [{"description":"cs", "question":"53f03ac07295ef2b467551d9" },
{"description":"physics","question":"53f03ac07295ef2b467551d9" }],
"title": "2134567890"
}]
}
All my code works fine without subjects area. I believe I have to override addhasmany or serializeHasMany in which I don't know the different between the two. But is the way I set up the JSON correct, and how would I write a serializer to serialize the subjects area correctly?
Thank you,
You can use the EmbeddedRecordsMixin http://emberjs.com/api/data/classes/DS.EmbeddedRecordsMixin.html you should be able to configure it easily to serialize and deserialize embedded relationships. Look at the 'embedded' : 'always' option from the first example