Im getting this error and am having trouble debugging it:
Uncaught Error: Attempted to handle event `deleteRecord` on <Todos.Todo:ember309:29> while in state root.loaded.updated.inFlight.
All transactions between ember and my JSON API seem to be working fine, but if alter the state of the todo, by either renaming it or checking it as complete, and then do a delete, I get the error above.
the changes they are persisting, and if I delete a todo without making any changes, that works as well.
Here is some code:
Route
Todos.TodosRoute = Ember.Route.extend({
model: function () {
return this.store.find('todo');
}
});
Controller
Todos.TodoController = Ember.ObjectController.extend({
actions: {
editTodo: function () {
this.set('isEditing', true);
},
acceptChanges: function () {
this.set('isEditing', false);
if (Ember.isEmpty(this.get('model.title'))) {
this.send('removeTodo');
} else {
this.get('model').save();
}
},
removeTodo: function () {
var todo = this.get('model');
todo.deleteRecord();
todo.save();
},
},
isEditing: false,
isCompleted: function(key, value){
var model = this.get('model');
if (value === undefined) {
// property being used as a getter
return model.get('isCompleted');
} else {
// property being used as a setter
model.set('isCompleted', value);
model.save();
return value;
}
}.property('model.isCompleted')
});
Adapter
Todos.ApplicationAdapter = DS.RESTAdapter.extend({
defaultSerializer: "Todos/todosREST",
serialize: function(record, options) {
var tmp = get(record, 'store').serializerFor(record.constructor.typeKey).serialize(record, options);
console.log('ser2:', tmp)
return tmp
},
createRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record, { includeId: false });
var tmp = this.ajax(this.buildURL(type.typeKey), "POST", { data: data });
// console.log('createRecord:', tmp, data, record);
return tmp;
},
updateRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record);
var id = get(record, 'id');
var tmp = this.ajax(this.buildURL(type.typeKey, id), "PUT", { data: data })
console.log(this.buildURL(type.typeKey, id), "PUT", { data: data })
return tmp;
},
namespace: 'api'
});
Serializer
Todos.TodosRESTSerializer = DS.RESTSerializer.extend({
typeForRoot: function(root) {
var camelized = Ember.String.camelize(root);
var tmp = Ember.String.singularize(camelized);
console.log('Camelized:'. tmp)
return tmp;
},
keyForAttribute: function(attr) {
return Ember.String.underscore(attr);
},
serialize: function(record, options) {
// client to server
var json = {};
record.eachAttribute(function(name) {
json[serverAttributeName(name)] = record.get(name);
})
record.eachRelationship(function(name, relationship) {
if (relationship.kind === 'hasMany') {
json[serverHasManyName(name)] = record.get(name).mapBy('id');
}
});
console.log('options: ', options)
if (options && options.includeId) {
json.id = record.get('id');
}
return json;
},
serializeIntoHash: function(hash, type, record, options) {
// hash should be an empty object, so just extend it
Ember.merge(hash, this.serialize(record, options));
},
extractSingle: function(store, type, payload, id, requestType) {
// server to client
console.log('in serializer')
return this._super(store, type, post_payload, id, requestType);
},
extractArray: function(store, type, payload, id, requestType) {
// server to client
console.log(payload, type)
var todos = payload.objects;
payload = {todos: todos}
return this._super(store, type, payload, id, requestType);
},
});
Anyone have any ideas?
Related
my model :-
App.bkModel = Backbone.Model.extend({});
collection :-
App.contactsCollection = Backbone.Collection.extend({
model: App.bkModel,
localStorage: new Backbone.LocalStorage("LibraryCollections"),
fetch: function(options) {
// check if localStorage for this collection exists
// (if needed, also check whether it's empty)
if(!localStorage.getItem("LibraryCollections")) {
var self = this;
$.ajax({
url: 'data.json',
}).done(function(response) {
$.each(response.items, function(i, item) {
self.create(item);
});
});
} else {
return Backbone.Collection.prototype.fetch.call(this, options);
}
}
});
var bkCollection = new App.contactsCollection;
for add and edit using addView
App.addView = Backbone.View.extend({
el: 'div.abPanel',
events: {
'submit form#frmAddContact': 'saveBook'
},
initialize: function () {
this.template = _.template(tpl.get('add-book'));
},
addBook: function (id) {
var book = {},
model = bkCollection.get(id);
//console.log(bkCollection.get(id));
if (id !== undefined && model !== undefined) {
book = model.toJSON();
}
this.$el.html(this.template({book: book}));
},
getInputValues : function () {
return {
title : $('#title').val(),
author : $('#author').val(),
quantity : $('#quantity').val(),
price : $('#price').val(),
description : $('#description').val(),
id : $('#id').val()
};
},
saveBook: function (event) {
var title = $('#title').val(),
author = $('#author').val(),
quantity = $('#quantity').val(),
price = $('#price').val(),
description = $('#description').val(),
id = $('#id').val();
if (id == '') {
bkCollection.create({title: title,quantity: quantity,author: author,price: price,description: description});
} else {
//this.collection.add(model, {at: position});
//var values = this.getInputValues();
//_.each(values, function (value, key) {
// bkCollection.set(key, value);
//});
//how to update here
}
return false;
}
});
for create working fine, how to update
update url like :- localhost/test1/#edit/cd235c1e-a153-8039-aedb-67609b5bcdef
help to solve this
I am trying to perform a search on my current collection and if the results aren't retrieved i am trying to query my search api
Collection:
var Backbone = require('backbone'),
_ = require('underscore'),
Urls = require('../../libs/urls'),
services = require('../../libs/services'),
skuListModel = require('../../models/sku/SkuListModel');
var SkuListCollection= Backbone.Collection.extend({
model: skuListModel,
sync: function (method, model, options) {
options = _.defaults({}, options, {
readUrl: Urls.sku.list
});
return services.sync.call(model, method, model, options);
}
});
View
searchData: function (e) {
var self = this;
var models = this.skuCollection.filter(function (item) {
return item.get("sku_code").indexOf(e.target.value) > -1
});
console.log(models);
if (models != null) {
self.skuCollection.set(models);
}
else {
self.skuCollection.fetch({
data: {
search_string: e.target.value
}
}).then(function (response) {
console.log(response);
//self.skuCollection.add(self.skuSearchCollection.toJSON(), { silent: true });
});
}
}
My question effectively is how do i modify my current collection to store the retrieved results and if my solution seems effective.
Move your filtering logic to the collection
Use promises to unify your response : an immediately resolved deferred if you find models, the xhr object if you have to fetch the data
Customize the behavior of fetch via the set options, e.g {remove: false} to keep the existing models
These points lead to a collection definition :
var SkuListCollection = Backbone.Collection.extend({
skus: function(code) {
var self = this;
var filtered = function() {
return self.filter(function (item) {
return item.get("sku_code").indexOf(code) !== -1;
});
};
var models = filtered();
if (models.length) {
// models found : define a promise and resolve it
var dfd = $.Deferred();
dfd.resolve(models);
return dfd.promise();
} else {
// models missing: fetch and add them
return this.fetch({
remove: false,
data: {
search_string: code
}
}).then(filtered);
}
}
});
Your view would then be rewired as :
searchData: function (e) {
this.skuCollection.skus(e.target.value).then(function(models) {
// do what you have to do with the filtered models
});
}
And a demo http://jsfiddle.net/nikoshr/84342xer/1/
i'm using the same code from this article (internationalization with angularjs)
...
but i need the "tables" variable to be fetched from an ajax request response using "$http get" but couldn't !! ... here is the code,
var xlat = angular.module('xlat', []);
xlat.factory('xlatService', function ($http) {
var currentLanguage = 'en';
// var tables = $.extend(true, {}, initialXlatTables);
var tables = {
'en': {
'textKeys.events': 'Events'
}
};
var service = {
getData: function () {
var req = {
method: 'GET',
url: 'local/en_US.php',
cache: true,
headers: {
'Content-Type': 'json'
}
};
$http(req).success(function (data) {
tables = data;
});
},
setCurrentLanguage: function (newCurrentLanguage) {
currentLanguage = newCurrentLanguage;
},
getCurrentLanguage: function () {
return currentLanguage;
},
xlat: function (label, parameters) {
service.getData();
if (parameters === null || $.isEmptyObject(parameters)) {
return tables[currentLanguage][label];
} else {
return $interpolate(tables[currentLanguage][label])(parameters);
}
}
};
return service;
});
but the variable "tables" does not change when i use the filter...
var xlat = angular.module('xlat', []);
xlat.filter('xlat', ['xlatService', function (xlatService) {
return function (label, parameters) {
return xlatService.xlat(label, parameters);
};
}]);
Try this one:
var xlat = angular.module('xlat', []);
xlat.filter('xlat', ['xlatService', function (xlatService) {
function myfiler(label, parameters) {
return xlatService.xlat(label, parameters);
};
myfiler.$stateful = true;
return myfilter;
}]);
Stateful filters -
https://code.angularjs.org/1.3.9/docs/guide/filter
Secod: you should load tables in factory method not in xlat function.
I have a model like below.
var FolderModel = Backbone.SP.Item.extend({
site: 'CapacityManagement',
list: 'Folder',
parse: function(response) {
var data = {};
if (response.d) {
data.Id = response.d.Id;
data.Active = response.d.Active;
data.FolderName = response.d.FolderName;
data.FolderTypeValue = response.d.FolderTypeValue;
data.ParentFolderID = response.d.ParentFolderID;
}
else {
data.Id = response.Id;
data.Active = response.Active;
data.FolderName = response.FolderName;
data.FolderTypeValue = response.FolderTypeValue;
data.ParentFolderID = response.ParentFolderID;
}
return data;
}
});
I am trying to update a model, but it is throwing an error in the parse function. The response variable is returning "undefined". But the code is working for creation and deletion.
This is how i am updating the value.
folder.save({'FolderName': data.FolderName}, {
success: function (model,response,options) {},
error: function (model, response, options) {}
});
I am having trouble looping through a collection that helps populate a view with data. When I try to loop through the collection and get the following error,
Uncaught TypeError: Object # has no method 'each'
I have absolutley no idea why I am getting this error, other than the object obviosly doesn't have that method, however I only get this error when I run the drop function see code below.
Here is by backbone code,
GroupListView.prototype.keyup = function() {
this.filtered = this.collection.searchName(this.$el.find("#search-query").val());
return this.renderList(this.filtered);
};
GroupListView.prototype.renderList = function(collection) {
var $collection, $this;
console.log(this.$el);
console.log(collection);
if (!collection) {
collection = this.collection;
console.log(collection);
}
this.$el.find(".list-items").empty();
$this = this.$el.find("#people-groups-list");
$collection = collection;
if ($collection.length < 1) {
this.$el.find("#people-groups-list").hide();
return this.$el.find("#people-groups-list").after('<div class="activity-no-show">\
<p>To add a new group, click the + in the top right hand corner to get started.</p>\
</div>');
} else {
this.$el.find("#people-groups-list").show();
collection.each(function(item) {
//console.log(item);
var displayView;
displayView = new app.GroupListDisplayView({
model: item,
collection: $collection
});
return $this.append(displayView.render());
});
return this;
}
};
GroupListDisplayView.prototype.render = function() {
var $body;
//console.log(this.model.toJSON());
this.$el.html(this.template({
m: this.model.toJSON()
}));
$body = this.$el.find(".card-body");
$.each(this.model.get("people"), function(i, person) {
var personTile;
this.person = new app.Person({
id: person.id,
avatar: person.avatar,
first_name: person.first_name,
last_name: person.last_name
});
console.log(this.person);
personTile = new app.PersonTileView({
model: this.person
});
return $body.html(personTile.render());
});
return this.$el.attr("id", "group-card-" + this.model.id);
};
GroupListDisplayView.prototype.drop = function(e) {
var $collection, $model, person_id, request;
e.preventDefault();
$collection = this.collection;
person_id = e.originalEvent.dataTransfer.getData('Text');
request = new app.PersonGroupAdd;
$model = this.model;
return request.save({
async: true,
wait: true,
person_id: person_id,
group_id: this.model.get("id")
}, {
success: function(d) {
return $model.fetch({
async: true,
wait: true
});
}
});
};
GroupListView.prototype.initialize = function() {
this.collection.on("change", this.renderList, this);
this.collection.on("reset", this.render, this);
return this.renderList();
};
Try this instead, place this function with in your collection
parse: function (data) {
data.forEach(function (item) {
displayView = new app.GroupListDisplayView({
model: item,
collection: $collection
});
});
}
Hope this helps.
I'm not sure what the drop function has to do with it, but I see renderList being passed the results of searchName during keyup. What's likely happening is that searchName is returning a regular array, instead of a wrapped object that would have the each method (i.e. a Backbone.Collection, jQuery collection or Underscore wrapped object).
Instead of calling collection.each, use jQuery or Underscore:
$.each(collection, function(i, item) { ... });
or
_.each(collection, function(item, i, list) { ... });