i want to update a record:
www.mywebsite.com/REST/mytable/16
But; for mytable, i have to give two mandatory parameters:
www.mywebsite.com/REST/mytable?param1=this¶m2=that
And if i want to take the model from this collection using the following, the record can't be found:
www.mywebsite.com/REST/mytable?param1=this¶m2=that/16
This is realized by the following code:
var Model = Backbone.Model.extend({
idAttribute : "ID"
});
var Col = Backbone.Collection.extend({
model : Model,
url : $scope.base + $scope.selected.table.entity.Name + "?param1=1¶m2=2"
});
connector.fetch().then(function () {
var record = connector.get(toBeChangedRecordId);
record.set(props); //attributes as json
.save({
success : $scope.putCallback,
error : $scope.putCallback
});
}
It doesn't work because in the url above, no record is found. Instead of this, i need another way, so i can just give my ID to change the record (thus www.mywebsite.com/REST/mytable/16 + JSON object. How is that possible?
When you are doing a dynamic URL like this you can wrap the url method in a function like so
Backbone.Model.extend({
idAttribute : "ID",
url: function() {
var idStr = ''
if (this.isNew()) {
idStr = '/' + this.get('id')
}
return 'http://www.mywebsite.com/REST/mytable' + idStr + '?param1=' + this.get('param1') + '¶m2=' + this.get('param2');
}
});
Also, you declared your url was semantically declared wrong. You have the query string in the wrong place.
Related
I want to get the Author field from Discussion forum list in SharePoint online using REST API in POST method. I tried the below approach, it is not working.
var queryUrl =
'?$select=ID,Title,Body,Author/Title,Folder/ItemCount,FieldValuesAsText/FileRef&$expand=Author,FieldValuesAsText,Folder/ItemCount';
var url =
siteUrl +
"/_api/Web/lists/GetByTitle('" +
listName +
"')/GetItems" +
queryUrl;
var camlQuery =
'<View><Query>' +
getQueryParams() +
"<OrderBy><FieldRef Name='DiscussionLastUpdated' Ascending='False'/></OrderBy></Query><RowLimit>12</RowLimit></View>";
var requestData = {
query: { __metadata: { type: 'SP.CamlQuery' }, ViewXml: camlQuery }
};
jQuery.ajax({
url: url,
method: 'POST',
data: JSON.stringify(requestData),
headers: {
'X-RequestDigest': $('#__REQUESTDIGEST').val(),
Accept: 'application/json; odata=verbose',
'Content-Type': 'application/json; odata=verbose'
},
success: function(data, status, jqXHR) {
dfd.resolve(data);
},
error: function(xhr) {
dfd.reject(xhr);
}
});
return dfd.promise();
The output is like below.
As I have explained in this post, $expand doesn't seem to work on some special columns (like People), when querying via POST. The best way will be to use the Items API.
However, if you only want to proceed with this approach then, try replacing the queryUrl value with the following.
var queryUrl ='?$select=ID,Title,Body,Folder/ItemCount,FieldValuesAsText/FileRef,FieldValuesAsText/Author&$expand=FieldValuesAsText,Folder/ItemCount';
Basically, what I am trying to do is that instead of directly querying the Author field, I am requesting it from under the FieldValuesAsText. Pretty much the way you have requested the FileRef property.
I am using the OData model to read data. But it doesn't work. Check the code below:
getGuid: function(pernr) {
var self = this;
var url = "/PersonalDetailSet?$filter=Pernr eq '00000001'";
self.setBusy(true);
this.oModel.read(url, {
success: function(res) {
// ...
},
error: function() {
// ...
}
});
}
I don't know why the filter in url is not working now?
Check if your OData service supports the $filter query in the first place.
Use the read method correctly:myV2ODataModel.read("/PersonalDetailSet"/* No $filter queries here! */, {
filters: [ // <-- Should be an array, not a Filter instance!
new Filter({ // required from "sap/ui/model/Filter"
path: "myField",
operator: FilterOperator.EQ, // required from "sap/ui/model/FilterOperator"
value1: "..."
})
],
// ...
});
API reference: sap.ui.model.odata.v2.ODataModel#read
API reference: sap.ui.model.Filter
First you check whether you are getting model in the scope or not. As i can see this.oModel which is not proper way of getting model. Better use this.getModel() or this.getView().getModel() and then check the call. Passing filter is not the right way but still it should work.
If you want to apply additional URL Parameters in the read function you have to do this via the "urlParameters" parameter:
getGuid: function(pernr){
var self = this;
var url = "/PersonalDetailSet";
self.setBusy(true);
this.oModel.read(url, {
urlParameters: {
"$filter" : "Pernr eq '00000001'"
},
success: function(res){
self.setBusy(false);
self.guid = res.results[0].Guid;
},
error: function() {
self.setBusy(false);
}
});
}
I want to select certain columns be returned back from sailsjs / waterline / API
Given the search parameters:
var searchParams = {
"select":["ClientTypeID"]
, "where": {
"or" :
[{"ClientType": {"contains": "MAINT"}}]
}};
I make API call :
/api/reference/client_type?select=ClientTypeID&where=%7B%22or%22:%5B%7B%22ClientType%22:%7B%22contains%22:%22MAINT%22%7D%7D%5D%7D
based on
Select specific fields from database
I believe I am making the correct query, however, the JSON object that is returned has the all the columns of entity vs the 1 I wish to request ClientTypeID?
This is known issue but I've found workaround. You can override default find blueprint with your own. You need to create api/blueprints/find.js file with content:
var _ = require('lodash');
var Promise = require('bluebird');
var actionUtil = require('sails/lib/hooks/blueprints/actionUtil');
var takeAliases = _.partial(_.pluck, _, 'alias');
var populateAliases = function (model, alias) {
return model.populate(alias);
};
module.exports = function (req, res) {
_.set(req.options, 'criteria.blacklist', ['limit', 'skip', 'sort', 'populate', 'fields']);
var fields = req.param('fields') ? req.param('fields').replace(/ /g, '').split(',') : [];
var populate = req.param('populate') ? req.param('populate').replace(/ /g, '').split(',') : [];
var Model = actionUtil.parseModel(req);
var where = actionUtil.parseCriteria(req);
var limit = actionUtil.parseLimit(req);
var skip = actionUtil.parseSkip(req);
var sort = actionUtil.parseSort(req);
var findQuery = _.reduce(_.intersection(populate, takeAliases(Model.associations)), populateAliases, Model.find().where(where).limit(limit).skip(skip).sort(sort));
var countQuery = Model.count(where);
Promise.all([findQuery, countQuery])
.spread(function (_records, _count) {
var records = fields.length > 0 ? _.map(_records, _.partial(_.pick, _, fields)) : _records;
return [records, null, null, {
criteria: where,
limit: limit,
start: skip,
end: skip + limit,
total: _count
}];
})
.spread(res.ok)
.catch(res.serverError);
};
This is general blueprint I'm using in all of my projects. For all fixed blueprints you can take a look here - https://github.com/ghaiklor/generator-sails-rest-api/tree/dev/generators/app/templates/api/blueprints
I'm running this code in a mongodb console:
var participantsWithoutCategory = db.participant.find({eventId: ObjectId("536d5564e7b237df30b628cc"), category: {$exists: false}});
var event = db.event.find({_id: ObjectId("536556c4eaa237df30b628cc")});
participantsWithoutCategory.forEach(function (entry) {
var userId = new ObjectId("" + entry._id + "");
var user = db.user.find( { _id: userId} );
print("got user: " + user);
});
and the result of the prints is:
got user: DBQuery: Oc5mjdKkhyDb3r6rhnzw.user -> { "_id" : ObjectId("536d8586ebb237df30b62bcb") }
so I'm just wondering how to get the actual object rather than a pointer to it?
if I try to get any of its properties such as user.dob I get a null :(
Turns out that's how mongo says that the query had no results... I've fixed it by using the right property of the object and not the _id but that's beyond the point.
The interesting thing here is that mongo gives back the DBQuery when find() returns nothing.
I am new to AngularJS, but have used Backbone for a while now.
I want to create a reusable restful api that I can pass the model name to so that I can use it for different models.
At the moment I have:
angular.module('healthplanApiServices', ['ngResource'])
.factory('Api', function($resource) {
return $resource(base_url + 'api/:object/:id', {
id : '#id', object : 'actions'
}, {
query : {
method : 'GET',
isArray : true,
callback : "JSON_CALLBACK"
},
save : {
method : '#id' ? 'PUT' : 'POST',
isArray : true,
callback : "JSON_CALLBACK"
}
});
});
... which sets the model as 'actions'. Then in my controller I use:
// get the collection
Api.query(function(r) {
$scope.actions = r;
});
$scope.toggleDone = function(a) {
a.done = !a.done;
//save an item
Api.save(a);
}
That's all fine, but how do I pass the model name ('actions' in this case) for each model type: e.g., instead of putting it in the factory function like so:
id : '#id', object : 'actions'
... but rather something more like:
var ActionApi = Api.setObject('actions');
ActionApi.query(function(r) {
$scope.actions = r;
});
UPDATE:
I just figured out a way. It may not be the best, but it does work. Any other suggestions would be welcome!
Just add the 'object' attribute to the model:
Api.query({object: 'actions'}, function(r) {
$scope.actions = r;
angular.forEach($scope.actions, function(a) {
a.object = 'actions' });
});
Api.save(a);// also works
You may want to try https://github.com/klederson/ModelCore ( ModelCore )
Its easy to model and structure and of course ... to use.
model.$find({ filter : "John" },{},true); //to find all with query parameters
model.$get(1); //to retreive the user with id 1
model.$save()
model.$deelte();
And so on.. checkout the documentation