making first attempt to master Ember.js atm. I'm trying to make a simple CMS, but for some reason I have a problem with getting any data from json displayed. I've already switched from Fixture to RESTAdapter, but I am still stuck with
Error: assertion failed: Your server returned a hash with the key timestamp but you have no mapping for it.
Here's my js code:
App.Store = DS.Store.extend(
{
revision:12,
adapter: 'DS.RESTAdapter'
}
);
App.Menucategory = DS.Model.extend({
timestamp: DS.attr('number'),
status: DS.attr('string')
});
App.MenucategoryRoute = Ember.Route.extend({
model: function() {
return App.Menucategory.find();
}
});
DS.RESTAdapter.reopen({
url: <my url>
});
DS.RESTAdapter.configure("plurals", {
menucategory: "menucategory"
});
Trying to access it with:
<script type="text/x-handlebars" id="menucategory">
{{#each model}}
{{data}}
{{/each}}
</script>
My json structure:
{
"timestamp": 1366106783,
"status": "OK",
"data": [
{
"name": "starters",
"id": 1
},
{
"name": "main dishes",
"id": 2
}]}
Thank you in advance for any help you can provide.
By default the RESTAdapter expects your API to be in a specific format, which your API doesn't conform to, if you can modify your API, you need to get it to return in this format, otherwise you'll need to customize the adapter.
Expected Format (based on your JSON):
{
"menucategory": [
{
"name": "starters",
"id": 1
},
{
"name": "main dishes",
"id": 2
}
],
"meta": {
"timestamp": 1366106783,
"status": "OK",
}
}
Related
I have trouble taking data from an API set. The body if viewed in Postman / Insomnia is as follows
{
"responses": {
"log": [
{
"id": 123,
"date": "2022-01-01T01:12:12.000Z",
"type": "online",
"details": [{
"detailId": "123-1",
"note": "success",
}]
},
{
"id": 124,
"date": "2022-01-01T01:12:12.000Z",
"type": "offline",
"details": [{
"detailId": "123-2",
"note": "failed",
}]
}
]
}
}
I want to take all data from log, as well from details. I used
adapt(item: any) {
return {
id: item.id,
date: item.date,
details: {
detailId: item.details.detailId,
note: item.details.note,
},
};
}
this returns id and date just fine. I also have a query to filter it based on type (online or offline), basically adding &type= into the API. It works for the online, but it returns detailId is undefined for offline (I used the same body, adapter and API minus the query for both data)
details is an array of object if you want to adapt it you need to do it iteratively.
adapt(item: any) {
const details = item.details.map(d => {detailId: d.id, note: d.note, …});
return {
id: item.id,
date: item.date,
details
};
}
Found the answer, apparently to make sure that I can get every value is to add ? after the [0], so it should be
details: {
detailId: item.details[0]?.detailId,
note: item.details[0]?.note,
},
I receive the following error when I use Ember Data to create records from a JSON response. What gives? I am following what the docs state.
Uncaught Error: Assertion Failed: Ember Data expected a number or string to represent the record(s) in the `user` relationship instead it found an object. If this is a polymorphic relationship please specify a `type` key. If this is an embedded relationship please include the `DS.EmbeddedRecordsMixin` and specify the `user` property in your serializer's attrs object.
JSON being parsed:
[
{
"id": 76,
"title": "Title",
"shipped": 0,
"date": "2015-05-21T05:00:00.000Z",
"user": {
"firstName": "First Name",
"lastName": "Last Name",
"email": "hellothere#gmail.com",
"id": 1
}
}
]
Shipment Model:
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
user: DS.belongsTo('user', { async: false })
});
Route:
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel: function() {
if(!localStorage.accessToken) {
this.transitionTo('login');
}
},
model: function() {
var shipmentObjects = [];
var App = this;
Ember.$.getJSON('http://localhost:1337/subscription/1/shipments/upcoming', function(shipments) {
shipments.forEach(function(data) {
var shipment = App.store.push('shipment', data);
shipmentObjects.pushObject(shipment);
});
});
return shipmentObjects;
}
});
You can create a custom serializer, if you can't modify your json response and manage to arrange data in other way
App.MODELNAMESerializer = DS.ActiveModelSerializer.extend({
extract: function(store, type, payload, id, requestType){
var shipments = [];
//CREATE A NEW PAYLOAD THAT EMBER CAN READ
var _payload = { };
return this._super(store, type, _payload, id, requestType);
}
});
Your json should look something like this
{
shipments: [
{
"id": 76,
"title": "Title",
"shipped": 0,
"date": "2015-05-21T05:00:00.000Z",
"user_id": 1,
}
],
"users": [
{
"firstName": "First Name",
"lastName": "Last Name",
"email": "hellothere#gmail.com",
"id": 1
}
]
}
Read the error message. It could hardly be clearer. By default, Ember Data expects an association to be represented by an ID. If the association is instead embedded, you must tell Ember Data that. You'll need something like:
// serializers/shipment.js
export default ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
user: { embedded: 'always' }
}
});
And remove the {async: false}, since the data is embedded right there.
See http://emberjs.com/api/data/classes/DS.EmbeddedRecordsMixin.html.
as I go deeper into EmberJS, I got into this context where I need to use HTTP request. As a start, I tried to retrieve JSON data so I made a test page that returns JSON and I also verified that it is in JSON by deserializing it. No errors were encountered but there is no output at all. Below are the details of my code
application.js
App = Ember.Application.create({});
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://172.19.20.30/EmberTest/testApi.aspx'
});
event.js
App.Event = DS.Model.extend({
title: DS.attr('string'),
body: DS.attr('string')
});
router.js
App.Router.map(function () {
this.resource('events', {path: '/'});
});
App.EventsRouter = Ember.Route.extend({
model: function () {
return App.Event.find();
}
});
JSON output from host
{ "events": [{ "id": 1, "title": "test title", "body": "test body" },{ "id": 2, "title": "another title", "body": "another body" }] }
HTML
<script type="text/x-handlebars" data-template-name="events">
this is an example
{{#each e in model}}
<label>{{e.title}}</label><br />
{{/each}}
</script>
what could possibly be missing in my code? comments, opinions, suggestions are greatly appreciated
Looks like the return JSON is wrong.. it should be singular:
{ "event": [{ "id": 1, "title": "test title", "body": "test body" },{ "id": 2, "title": "another title", "body": "another body" }] }
When you do a find with Ember Data it should have the model name:
this.store.find('event') So Ember-data know where the return map to.
This will generate a URL http://host:port/event
If you are changing host it should just be the base URL you are changing and not absolute. So in your case:
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://172.19.20.30/EmberTest'
});
Then the URL will become http://172.19.20.30/EmberTest/events
Lets assume I have an mongodb items collection looking like this (MongoLab):
{
"_id": {
"$oid": "531d8dd2e4b0373ae7e8f505"
},
"tags": [
"node",
"json"
],
"anotherField": "datahere"
}
{
"_id": {
"$oid": "531d8dd2e4b0373ae7e8f505"
},
"tags": [
"ajax",
"json"
],
"anotherField": "datahere"
}
I would like to get all items where a node is within the tags array.
I've tried the below, but no success - it is returning all items - no search performed?
Plunker demo : http://plnkr.co/edit/BYj09TOGyCTFKhhBXpIO?p=preview
// $route.current.params.id = "node" - should give me only 1 record with this tag
Restangular.all("items").customGET("", { "tags": $route.current.params.id });
Full example, return same record for both cases:
var all = db.all('items');
// GET ALL
all.getList().then(function(data) {
$scope.all = data;
console.log(data);
});
// SEARCH for record where "tags" has got "node"
all.customGET('', { "tags": "node"}).then(function(data) {
$scope.search = data;
console.log(data);
});
Any suggestion would be much appreciated.
According to Mongolab REST API Documentation you have to pass the query object with the q parameter. In your case it is q={"tags":"node"}.
Using Restangular it will be like this:
Restangular.all("items").customGET('', { q: {"tags": "node"}})
[{"id":1,"name":"ABC"},{"id":2,"name":"XYZ"}]
This is how the data is returned by the controller in json format
I want to store it in the following format:
var json = {
"users": [
{ "id": "1", "name": "ABC" },
{ "id": "2", "name": "XYZ" },
]
}
Following is the code I have used but doesnt work.
var json =
{
"users": $.getJSON("#Url.Action("SearchCMSAdmins")")
}
$("#DistributorCMSAdmin").tokenInput("#Url.Action("SearchWithName")", {
theme: "facebook",
preventDuplicates: true,
prePopulate:json.users
});
Any help is appreciated. Thanks in advance.
$.getJson is asynchronous, so you need to use the success callback for getting the response and doing the operation. Try this INstead.
$.getJSON("#Url.Action("SearchCMSAdmins")",function(data){
var json= {"users":data};
$("#DistributorCMSAdmin").tokenInput("#Url.Action("SearchWithName")", {
theme: "facebook",
preventDuplicates: true,
prePopulate:json.users
});
});