Payload Empty when Passing in Non-Restful Action in Backbone - backbone.js

How do I pass in data when I need to POST to a non-restful action within the Model?
For Example...
module.exports = Base.extend( {
url: {
'create': '/sites/:site_id/footer',
'update': '/sites/:site_id/footers/:activity',
'copy': '/sites/:site_id/:language/:label/footer/copy',
'delete': '/sites/:site_id/footer/:id'
},
api: 'service',
copy: function () {
var new_label = this.get( 'label' ) + ' Copy';
return this.save( {}, {
type: 'POST',
url: this._getUrl( 'copy' ),
data: JSON.stringify( {
action: 'copy',
label: new_label
} )
} );
}
} );
Problem is that whenever we pass in the data... payload only shows 'action'. Label is completely ignored.

Try this instead:
copy: function () {
var new_label = this.get( 'label' ) + ' Copy';
return this.sync(
'create',
this,
{
url: this._getUrl( 'copy' ),
attrs: {
action: 'copy',
label: new_label
}
}
);
}
This is basically the magic behind the save function without all the auto collection the data to send. Note the if you use the attrs key in the options then you don't need to stringify the data yourself as it will be done for you in the sync method.

Related

How to pass data from $state.go() to the data parameter in stateprovider in angular?

I am having trouble passing some data to the stateprovider using $state.go(). Here is the sample code that we have been using.
$stateProvider.state('socialform', {
url: "/socialform?webcontent",
templateUrl: "base_template/_Sends.html?",
data: { pageTitle: 'Social & Website Publishing' },
resolve: {
callPreRenderServices: callPreRenderServices
}
});
$scope.isWebContent = function(status) {
if(status) {
$state.go('socialform', {webcontent:true});
}
else {
$state.go('socialform');
}
};
Basically, what we need to be doing is to pass a title variable to $state.go() so that it will replace the pageTitle to whatever is the value of the passed variable.
From the code above to this:
$stateProvider.state('socialform', {
url: "/socialform?webcontent",
templateUrl: "base_template/_Sends.html?",
data: { pageTitle: title },
resolve: {
callPreRenderServices: callPreRenderServices
}
});
$scope.isWebContent = function(status) {
if(status) {
$state.go('socialform', {webcontent:true, title:"some title"});
}
else {
$state.go('socialform', {title:"another title"});
}
};
You could use a service :
module.service('titleService', function() {
this.title = null;
});
// ... inject titleService in the calling controller ...
$scope.isWebContent = function(status) {
if(status) {
titleService.title = 'Some Title'
$state.go('socialform');
}
else {
titleService.title = 'Another Title'
$state.go('socialform');
}
};
Then, you can either inject it in via custom data or, via the resolve function :
// ... inject before route definition, via dependency injection
data = { title: titleService.title };
$stateProvider.state('socialform', {
url: "/socialform?webcontent",
templateUrl: "base_template/_Sends.html?",
// like this
data: data,
resolve: {
callPreRenderServices: callPreRenderServices
// Or you can resolve your title from your service
// and use pageTitle in your controller
pageTitle: ['titleService', function(titleService) {
return titleService.title;
}]
}
});
You could also pass it as a $state parameter :
$stateProvider.state('socialform', {
url: "/socialform/:webcontent/:title",
// ...
});
// ...
$state.go('socialform', {webcontent: 'something', title: 'some other thing'});

JS-Data error: attrs must contain the property specified by idAttribute - with hasMany relations

Here's the error:
http://puu.sh/lXzja/f773fb6c9a.png
The primary key for my user model is username. The primary key for my routes is the routename. My api returns jsons inside data:{} as per jsonapi.org specs. Thus the id attribute is not in the top-level, as js-data demands. This is why I return data.data in the afterFind for 'users'. I tried to do something like that in 'routes' but it's an array of routes.
The console log in beforeInject gives me:
result in beforeInject
Here's the config:
DS.defineResource({
name: 'users',
idAttribute: 'username',
basePath: apiEndpoint,
relations: {
hasMany: {
routes: {
localField: 'routes',
foreignKey: 'username'
}
}
},
// set just for this resource
afterFind: function(resource, data, cb) {
// do something more specific to "users"
cb(null, data.data);
}
});
DS.defineResource({
name: 'routes',
idAttribute: 'routename',
basePath: apiEndpoint,
cacheResponse: true,
relations: {
belongsTo: {
users: {
parent: true,
localKey: 'username',
localField: 'users'
}
}
},
beforeInject: function(resource, data) {
// do something more specific to "users"
console.log(data);
return data.data.routes;
}
});
Here's where I try to load my routes but get that err:
resolve: {
user: function($route, DS) {
var username = $route.current.params.username;
return DS.find('users', username).then(function(user) {
DS.loadRelations('users', user.username, ['routes']).then(function(user) {
console.log(user);
}, function(err) {
console.log(err);
});
});
}
}
Not only is your data nested under a "data" field, but a "routes" field. So when you find the routes, you're trying to inject something like:
{
routes: [{
// foreignKey to a user
username: 'john1337',
// primary key of a route
id: 1234
}]
}
when you need to be injecting:
[{
username: 'john1337',
id: 1
}]
Add an afterFindAll on your routes resource to cb(null, data.data.routes).
You'll either need to:
A) Add lots of "after" hooks to all your Resources or
B) Make the deserialization generic so it works for all Resources. Perhaps something like this?
DS.defaults.afterFind = function (Resource, data, cb) {
cb(null, data.data[Resource.name])
};
DS.defaults.afterFindAll = function (Resource, data, cb) {
cb(null, data.data[Resource.name])
};

Get property of JSON

I have the following on an angular controller:
$scope.emailsConfig = {
valueField: 'email',
labelField: 'name',
options: [{email: 'brian#dn.cm', name: 'Brian'},
{email: 'nikola#tl.com', name: 'Nikola'}],
}
Then I have the following:
<select selectize="emailsConfig" ng-model="emails"></select>
This works fine ... But then I changed options to:
options: UserService.GetEmails()
This does not work. When I logged options and get:
{"Emails":[{email: 'brian#dn.cm', name: 'Brian'}, {email: 'nikola#tl.com', name: 'Nikola'}]}
How can I get the values that are in Emails?
I tried UserService.GetEmails().Emails but somehow get undefined
UPDATE
UserService.GetEmails() is the following:
application.service('UserService', function ($http) {
return {
GetEmails: function () {
return $http.get('api/users/emails');
}
}
}
The service is returning the promise that $http returns. You still need to add the callback that returns the data. Can use success() or then()
Try this:
UserService.GetEmails().success(function(resp){
$scope.emailsConfig = {
valueField: 'email',
labelField: 'name',
options: resp.Emails
}
}).error(function(){
alert('Ooops')
});
to move more of this into the service and out of the controller you could do something like:
application.service('UserService', function ($http) {
return {
GetEmails: function (callback) {
$http.get('api/users/emails').success(function (resp) {
var config = {
valueField: 'email',
labelField: 'name',
options: resp.Emails
}
callback(config);
}).error(function () {
alert('Oooops');
});
}
}
}
then in controller
UserService.GetEmails(function(emailsConfig){
$scope.emailsConfig = emailsConfig;
})

With Backbone.Forms is there a way to set the select editor option after loading a collection

I have a form with a select editor type which uses a collection, but I have not found any way of setting the selected option after the data is loaded. I have not found anything in the documentation or any examples online.
...
country: {
title: 'Country',
type: 'Select',
options: function (callback) {
var result = [];
var states = new Countries();
states.fetch({
success: function (collection) {
_.each(collection.models, function (model) {
result.push({ 'val': model.get('id'), 'label': model.get('name') });
});
callback(result);
}
});
},
validators: ['required']
},
...
you can use
form.getEditor('country').setValue('YourVal')

CakePhp sending response as Json and displaying it

i am trying to auto complete department using jquery autocomplete library.
ajax call is as follows
$( "#auto_complete" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "/employees/getDepartment"
dataType: "jsonp",
//dataType: "text/html",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function( data ) {
alert("success--");
response( $.map( data.geonames, function( item ) {
return {
label: item.name,
value: item.id
}
}));
}
});
},
minLength: 2,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
my controller has a action called getDepartment is as follows:
public function getDepartment() {
$this->log($this->params->query['name_startsWith'] , 'debug');
$str = $this->params->query['name_startsWith'];
$this->log($str, 'debug');
$name='Departmet';
$this->layout = 'ajax';
$departments = $this->Employee->Department->find('all', array( 'recursive' => -1,
'conditions'=>array('Department.name LIKE'=>$str.'%'),
'fields'=>array('name', 'id')));
$this->set('departments',$departments);
}
here i need to send the $departments as Json .
how to send the response as JSON
why controller is not reaching autocomplete success function (where i have put an alert)
when i run i get response (using fireBug) as
[{"Department":{"name":"Testing","id":"1"}},{"Department":{"name":"Testing","id":"3"}},{"Department":{"name":"Testing2","id":"6"}},{"Department":{"name":"testing","id":"7"}},{"Department":{"name":"test","id":"8"}}]
Your response is valid JSON and so your dataType must be too.
dataType: "json"

Resources