There are a few bits of additional information that will help us get the right source of the problem. I think we can do without them, but if we get stuck, I would like to know:
- Are there any errors in the browser console?
- What does the
appSettings.searchPath search appSettings.searchPath URL look appSettings.searchPath ?- Does it contain colon prefix parameters?
- What request does your endpoint expect?
- Do you include jQuery or jQuery Lite in addition to Angular?
Just in order to fix everything, I'm going to assume that in fact you are not getting any console errors, and you have included the necessary libraries for both Angular and jQuery.
If this is the case, here are some tidbits that can help.
When you use $request factory, you create a kind of interface that abstracts the execution of HTTP requests. Since you are using this for search, call this search interface.
If you execute a GET request through your query search method, you can pass any object or array and construct the URL with the request based on this argument.
For example, suppose you passed in your newRequest as-is variable, without any processing. This will result in a URL request, for example the following (decoded for readability):
?Facets={"Field":"createdBy","Value":"Joe"}&Facets={"Field":"createdBy","Value":"Mary"}&PageSize=25&SearchTerms=error
Note that the Facets parameter is specified twice? Once for each element in your Facets array. This may work if your endpoint supports queries in this format.
On the other hand, using the jQuery $.param , as you tried to do in this fragment from your first example ...
{ query: { method: 'GET', transformRequest: function (data, headersGetter) { if (data === undefined) { return data; } return $.param(data); } }
... theoretically you would get a URL query string like this (decrypted for reading):
SearchTerms=error&PageSize=25&Facets[0][Field]=createdBy&Facets[0][Value]=Joe&Facets[1][Field]=createdBy&Facets[1][Value]=Mary
Why "in theory?" Well, as it turns out, you cannot use $request this way, for several reasons.
'query' uses HTTP GET
First, the HTTP method that you specify for query will determine what happens to the parameter object that you pass to this query method.
Assuming query uses an HTTP GET (as in your examples), the parameter object will be serialized and appended to the endpoint URL. You will end up with a URL that has something like this:
?Facets={"Field":"createdBy","Value":"Joe"}&Facets={"Field":"createdBy","Value":"Mary"}&PageSize=25&SearchTerms=error
Using an HTTP GET, you basically say that the data you want to send with the request is embedded in the URL.
This happens regardless of any processing specified in transformRequest .
In fact, since this query action is not HTTP POST (it is GET), there is no data to publish because it is that GET works differently than POST (reading using HTTP methods if this is a new territory for you). Therefore, your transformRequest function receives a data argument that is undefined .
What if we used HTTP POST?
Suppose you configured query to use HTTP POST. In this case, the parameter object that you pass when calling query will be placed in the mail data (request payload) of your HTTP request. It will not be added to the URL, as was done with GET.
Using HTTP POST, you are now declaring that the data you want to send can be found in the request body (and not in the URL).
Since there is “data” for publication, the parameter object that you pass to query will be available as the data argument in your transformRequest function. This is good because you cannot just send a raw object like newRequest for example. You will need to serialize it to a string. Otherwise, you will receive messages such as:
[object Object]
But since this is now POST, you no longer need to format it as a URL request (since it does not get to the URL). You can use any data format that the destination wants to receive. If you are using a JSON endpoint, you can send a JSON-encoded version of your newRequest object by doing something like this in your transformRequest function:
return JSON.stringify(data)
But what if we should use GET?
Sometimes you have no control over the endpoint. What if only the GET requests for this search API you want to use? And what if he wants to get a very specific URL request format?
Not a problem ... to the point.
When you create your search interface using $request factory, you can specify the resource URL with parameters .
Say your final URL of your search is:
/search.do
And he wants to see GET requests with URLs such as:
/search.do?PageSize=25&SearchTerms=error
Then you will create your search interface with a parameterized URL:
$resource("/search.do?PageSize=:PageSize&SearchTerms=:SearchTerms")
So you can pass the request, for example:
searchResource.query({PageSize: 25, SearchTerms: "error"}, successCallback);
To make a GET request with a URL:
/search.do?PageSize=25&SearchTerms=error
Unfortunately, this starts to break up with unlimited parameter lists, such as your Facets array. The previous template requires you to have a fixed list of arguments.
Don't forget that if your endpoint is not too picky, you can always just send a GET request with URL serialization like this:
?Facets={"Field":"createdBy","Value":"Joe"}&Facets={"Field":"createdBy","Value":"Mary"}&PageSize=25&SearchTerms=error
which means $resource for your newRequest object newRequest free.
Let it get complicated
What if you really REALLY want to use $request and you need to send GET requests that look like the output of $.param ?
Good. Let me get some fantasy. JS fancy.
If you are only going to use the query method in your search interface, you can simply wrap the object created by $resource .
.factory("searchResource", ["$resource", searchResource]); function searchResource($resource) { var searchDelegate = $resource("/search.do?:queryString"); var searchInterface = { query: function (params) { var encodedQuery = $.param(params); return searchDelegate.query({queryString: encodedQuery}); } }; return searchInterface; }
Now you can pass the newRequest object as is, and your loaded search resource will make a GET request to this URL (decoded for readability):
search.do?SearchTerms=error&PageSize=25&Facets[0][Field]=createdBy&Facets[0][Value]=Joe&Facets[1][Field]=createdBy&Facets[1][Value]=Mary