OData substringof or startswith returning all items - rest

I'm trying to filter my results from a Rest Call.
$.ajax({
type: "GET",
headers: {
"Accept": "application/json;odata=verbose"
},
dataType: "JSON",
url: _spPageContextInfo.webServerRelativeUrl + "/_api/lists/getByTitle('Contacts')/items?$select=Title,Id&$startswith('Title','" + request.term + "') eq true",
success: function (data) {
},
error: function (ex) {
}
});
In my Contacts List i'm trying to retrieve the Title and the Id for Items which start with a String or which have the String somewhere in it, here for example it is the Name of somebody.
I also tried it with substringof:
"/_api/lists/getByTitle('Contacts')/items?$select=Title,Id&$substringof(" + request.term + ",'Title') eq true"
which delivers also the same result.
It gives me all List Items from the List and no Filtering is applied.
I build the Url for the Rest after looking here Programming using the SharePoint 2013 REST service
Like the Schema given there I think the Url looks ok, but it not seems so :)
Edit:
Applying the $filter like in the OData Uri Conventions gives me the following error:
{"error":{"code":"-1, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"The query is not valid."}}}
Tried it with following Query Strings:
_api/lists/getByTitle('Contacts')/items?$select=Title,Id&$filter=substringof(m,'Title') eq true
_api/lists/getByTitle('Contacts')/items?$select=Title,Id&$filter=substringof('m','Title') eq true
_api/lists/getByTitle('Contacts')/items?$select=Title,Id&$filter=substringof('m',Title) eq true

I've managed to get the filter with substringof returning the correct results when I removed the "eq true".
Using one of your query strings, it should work like this:
_api/lists/getByTitle('Contacts')/items?$select=Title,Id&$filter=substringof('m',Title)
I haven't checked any other functions, but at least, the same happens with startswith function.

For anyone looking at this question, I can report that
/_api/web/lists/GetByTitle('Applications')/items?$filter=startswith(Title,'1AAJ')
IS working for me.

I tried your query URI on my endpoint and applied some changes:
- The second parameter of the substring shouldn't be a string, so I removed the apostropes
After this I get the results:
http://jaydata.org/examples/Northwind.svc/Products?$select=Product_ID,Product_Name&$filter=substringof('CH',Product_Name)
My endpoint is standard WCF Data Service, and the filter is working.
If changing the URI still returns all records, that would be a SherePoint trick I guess. What happens if you put 'zzz' or some random string in the filter?

Check http://www.odata.org/documentation/odata-v2-documentation/uri-conventions/ for the correct uri convention.
Should be
/_api/lists/getByTitle('Contacts')
/items?$select=Title,Id&$filter=substringof(" + request.term + ",'Title') eq true"
So with the $filter included

Also, the contains method works and I've had better compatibility with it. The syntax is:
api/People?$filter=contains(LastName,%27Smith%27)&$select=LastName,FirstName

Related

RTK Query url with parameter which is an array

I am currently trying to pass in an array to a query which will be used as parameters but keeping encountering an issue that the object doesn't seem to take an array in the parameters and doesn't format the url param string as I need.
Here is my array that is passed into my RTK hook:
filterArguments = [1,2]
RTK Query:
getFood: builder.query({
// The URL for the request is '/fakeApi/posts'
query: (filterArguments) => ({
url:'/user/food/',
params: {
...filterArguments
}
}),
providesTags:['Food']
}),
This is bringing back an error or if i fiddle around with it an send an object through it brings back the following URL ignoring other items in the object of the same name:
test:8000/api/?filter=1
However this is not the desired result, the desire url result from passing an array of filter id's would be:
test:8000/api/?filter[]=1&filter[]=2
is this achievable in RTK query? and how would i achieve this?
redux-toolkit doesnt implement any special http library. It uses fetch under the hood. For params, it uses URLSearchParams(). So the API will be similar. Since URLSearchParams() doesnt support your params notation, you can use the query-string library:
const queryString = require('query-string');
getFood: builder.query({
query: (filterArguments) => ({
url:'/user/food/' + queryString.stringify({filter: filterArguments}, {arrayFormat: 'bracket'}),
}),
providesTags:['Food']
}),

REST API - Endpoint syntax - get item by property - not by id

I'm implementing my first REST API, and I have a question about the syntax of the URL endpoints.
I know that I should use these endpoint for get, create, update and delete:
Get list of items
Method: GET, Url: /api/items
Get item by id
Method: GET, Url: /api/items/:id
Add item (new item data in the request body)
Method: POST, Url: /api/items
Modify item (modified item data in the request body)
Method: PUT, Url: /api/items/:id
Delete item
Method: DELETE, Url: /api/items/:id
But lets say the interface of item is
interface item
{
id: string;
name: string;
}
What should be the request url for getting an item by it's name?
I can't use Method: GET, Url: /api/items/:name, because this will match the get-by-id request. So how should I syntax this endpoint?
There is no standard REST URI syntax unless you are doing OData for example. You have perfect freedom designing your own URIs, even /resource/{id} is perfectly valid.
What I like to do is end the URIs of collections with / and use queries for filtering collections. So I would do /api/{version}/items/?name={name} if they have unique names and you expect an item instead of a collection, then I would do it this way: /api/{version}/items/name:{name}. But this is my style.
From client perspective the URI syntax is totally irrelevant, because the server gives the valid URI templates to the client according to the HATEOES constraint. If you thought otherwise, then probably you are building a CRUD API instead of a REST API.
You chould use a filter on the collections endpoint like:
Method: GET, Url: /api/items?name=foo
This filter could return all items which have a foo string in them (depending on how you want to handle wildcards in the search / filter term), e.g. the response could be a collection of items:
{
"data": [
{
"id": "d079d8e9-4d24-4514-b356-78587f6c2ba9",
"name": "foo"
},
{
"id": "7f5e558c-6a7f-4ebe-8f4f-a2d029a803ed",
"name": "foo bar"
}
]
}
If you want the response to return a single resource you could also use the name as identifier and apply the scheme from above using the name, e.g.
Method: GET, Url: /api/items/:name

Query sailsjs blueprint endpoints by id array using request

I'm using the request library to make calls from one sails app to another one which exposes the default blueprint endpoints. It works fine when I query by non-id fields, but I need to run some queries by passing id arrays. The problem is that the moment you provide an id, only the first id is considered, effectively not allowing this kind of query.
Is there a way to get around this? I could switch over to another attribute if all else fails but I need to know if there is a proper way around this.
Here's how I'm querying:
var idArr = [];//array of ids
var queryParams = { id: idArr };
var options: {
//headers, method and url here
json: queryParams
};
request(options, function(err, response, body){
if (err) return next(err);
return next(null, body);
});
Thanks in advance.
Sails blueprint APIs allow you to use the same waterline query langauge that you would otherwise use in code.
You can directly pass the array of id's in the get call to receive the objects as follows
GET /city?where={"id":[1, 2]}
Refer here for more.
Have fun!
Alright, I switched to a hacky solution to get moving.
For all models that needed querying by id arrays, I added a secondary attribute to the model. Let's call it code. Then, in afterCreate(), I updated code and set it equal to the id. This incurs an additional database call, but it's fine since it's called just once - when the object is created.
Here's the code.
module.exports = {
attributes: {
code: {
type: 'string'//the secondary attribute
},
// other attributes
},
afterCreate: function (newObj, next) {
Model.update({ id: newObj.id }, { code: newObj.id }, next);
}
}
Note that newObj isn't a Model object as even I was led to believe. So we cannot simply update its code and call newObj.save().
After this, in the queries having id arrays, substituting id with code makes them work as expected!

REST issue Sharepoint 2013

I'm using the REST interface for Sharepoint 2013 to retrieve some elements from a list.
Here is my function :
<script type="text/javascript">
function getAllProgramName(){
// Getting our list items
var call = $.ajax({
url: "https://aleinternational.sharepoint.com/sites/CapexRequest/_api/web/lists/getByTitle('Program')/items?$filter=Year eq '2015'&$select=Program_x0020_name",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
});
call.done(function(data,textStatus,jqXHR){
alert('success'+jqXHR.responseText);
});
call.fail(function(data,textStatus,jqXHR){
alert('success'+jqXHR.responseText);
});
}
</script>
But I always get a correlation ID error when I have two operations in the url (here, I have $select and $filter).
If I remove the $filter or the $select operation, it works fine.
Do you guys have any idea?
Thanks !
#user3206787 I recently wrote one REST code.
With regards to your query i changed the sequence of $filter and $select. Still query returns the results. so sequence of $select and $ filter wont matter.
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('Exit%20Test%20Questions')/Items?$filter=ExitTest/Id eq "+$scope.selectedTest.Id+"&$select=Title,Answer,Id,QuestionType,ExitTest/Id&$expand=ExitTest/Id",
/_api/web/lists/getbytitle('Exit%20Test%20Questions')/Items?$select=Title,Answer,Id,QuestionType,ExitTest/Id&$expand=ExitTest/Id&$filter=ExitTest/Id eq "+$scope.selectedTest.Id
Please check two things :-
Pass year as int:2015 instead of as string:'2015'
In select first try fetching basic Title column [$select=Title] and
then if it is fetching required result then go for complex column
name like Program_x0020_name.

Sharepoint 2013 REST API not returning all items for a list

The title states my problem quite exactly. If I try to gather all 400+ items from a list using sharepoint's REST API, I only get first 100.
I have read http://msdn.microsoft.com/en-us/library/office/dn292552(v=office.15).aspx and in the "Working with list items by using REST" part, they're stating that
The following example shows how to retrieve all of a list’s items.
url: http://site url/_api/web/lists/GetByTitle(‘Test')/items
method: GET
headers: ...
I have highlighted word all, because that's not what I'm getting ...
Am I missing something? Is there some option I should disable/enable to gett truly all items?
Thanks
The limitation is due to server side paging.
A workaround is to retrieve 100 items at a time, or override the limitation by entering a count of items:
https://$DOMAIN/$SITE/_api/web/Lists/getByTitle('$LIST')/Items?$top=1000
Note that there is also a threshold at 5000.
You can use RowLimit & RowsPerPage in rest call. Below is the example
$.ajax({
url: siteurl + "/_api/web/lists/getbytitle('NewList')/items",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
RowLimit : null, //Specify the row limit
RowsPerPage : null, //Specify no of rows in a page
success: function (data) {
$('#oDataFilter').append("<table>");
$.each(data.d.results, function(index, item){
$('#oDataFilter').append("<tr><td class="+styleClass+">" + item.ID + "</td><td class="+styleClass+">"+ item.Title + "</td></tr>");
});
$('#oDataFilter').append("</table>");
},
error: function (error) {
alert('Error getListItems :: '+JSON.stringify(error));
}
Adding to Christophe's answer I would say listing all (potentially 5000) items in a list and parsing them would result in performance issues.
If you query sharepoint to show all items in a particular list it would only print out the first 100. But the xml response also provides the url to query for the next 100 list items.
At the very end of the xml response you will see a tag like this
<link rel="next" href="https://xxxxx.sharepoint.com/_api/web/lists/GetByTitle('list')/items?%24skiptoken=Paged%3dTRUE%26p_ID%3d100" />
The url inside href="...."is what you'll need.
Querying the above would provide you with a list of the next 100 or less items.
If there are still more items left this xml response would in turn provide an other <link rel="next"> tag and if not this tag won't exist.
Better to handle 5000 items in sets of 100 rather than them all together in my opinion.
To anyone now seeing this, you can use data.d.__next to get the next 100 items. Using some good old recursion, you can get all the items like so
function getItems(url) {
$.ajax({
url: url,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
},
success: function(data) {
console.log(data);
// Do work
if (data.d.__next) {
getItems(data.d.__next);
}
},
error: function(jqxhr) {
alert(jqxhr.responseText);
}
});
}