I have a GET endpoint with URI as /user/user-id . The 'user-id' is the path variable here.
How can I set the path variable while making the GET request?
This is what I tried:-
$http.get('/user/:id',{
params: {id:key}
});
Instead of replacing the path variable, the id get appended as query param.
i.e my debugger show the request URL as 'http://localhost:8080/user/:id?id=test'
My expected resolved URL should be like 'http://localhost:8080/user/test'
$http's params object is meant for query strings, so key-value pairs you pass into params are output as query string keys and values.
$http.get('/user', {
params: { id: "test" }
});
Becomes: http://localhost:8080/user?id=test
If you need http://localhost:8080/user/test, you can either:
Construct the url yourself,
$http.get('/user/' + id);
Or, use $resource (specifically $resource.get https://docs.angularjs.org/api/ngResource/service/$resource). This is a little cleaner.
Why not something like this?:
var path = 'test';
$http.get('/user/' + path, {});
Related
I have a resource, Answer, which has a composite key made of QuestionnaireId and QuestionId. The ngResource code is as follows:
function answerResource($resource) {
return $resource("/api/answers/:questionnaireId/:questionId",
{
questionnaireId: "#questionnaireId",
questionId: "#questionId"
}
);
}
I want to query this resource with the the questionnaire Id and get back all the answers. If I use:
answerResource.query(
{
questionnaireId: questionnaireId
}
);
Then the requested url is:
/api/answers/123
When I want it to be:
/api/answers?questionnaireId=123
Otherwise I have two routes that I need to handle for the query search - one with the Id in the querystring, the other with the Id as part of the url path. (I also have queries with search text where the questionnaire Id might not be present, that would use urls like /api/answers?q=sometext).
Surely any .query parameters should be passed as querystrings, not as part of the route. How do I get the desired behaviour?
The best option I can come up with, is to create a new search method on the resource, which doesn't have the parameters in the url:
// normal resource definition here...
,{
search: {
method: "GET",
url: "/api/answers",
isArray: true
}
}
Calling that with the composite key values will append them as querystring parameters and not as part of the url, e.g. /api/answers?questionnaireId=123
Faced a similar issue, but I'm messing with composite key (item, sequence).
1- html.erb: Borrowed option 2 from https://spin.atomicobject.com/2013/11/22/pass-rails-data-angularjs/
That way I could grab inside the .js script the item from the .erb form I already have (I'm doing some kind of "manage details -- crud" on request with angularjs)
2- in the controller .js file I grab the value from the custom data in the html element using document.getElementById and getAttribute, concatenating that to the request: '/items?personId='+div.getAttribute("data-personId")+'&format=json'
3- in the items_controller index action, by default rails g expects no argument and grabs all items, then I had to ask
if params[:personId].present?
#items = Item.where(personId: params[:personId])
else
grab-all-items
end
This works, but I'm not sure if it's the best approach because I'm a real newbie for angularjs.
Just messing with this issue, cannot figure yet how to remove a record.
$resource crete path instead of querystring because you define placeholders :
return $resource("/api/answers/:questionnaireId/:questionId"..
If you delete them from resource-level and then call $resource.query({param: value}) you can make querystring, also you can specify more actions for single $resource to perform different request overriding action url property.
I created a simple (and very fast) example might help you understand:
working example :https://jsfiddle.net/Nedev_so/b71feyc6/19/
EDIT :
after your comment i understand what you need, so
resource factory :
//only for example purpose
var answersBaseUrl = "https://example.com/api/answers";
var answerTemplateUri = commentsBaseUrl + '/:questionnaireId/:questionId'
var params = {questionnaireId: '#_questionnaireId',questionId: '#_questionId'};
var res = $resource(answerTemplateUri, params,{
one :{
method: "GET",
},
all: {
method: "GET",
url: answersBaseUrl,
isArray: true
}
});
return res;
});
and then in your controller :
//get answers by questionnaire
//GET /answers?questionnaireId=123
$scope.answersByQuestionnaire = answers.all({questionnaireId: 123});
//get answers by question
//GET /answers?questionId=123
$scope.answersByQuestion = answers.all({questionId:123});
//get single answer by questionnaire and question
//GET /answers/123/123
$scope.answer = answers.one({questionnaireId: 123,questionId:123 });
(check network logs and you can see expected behaviour)
Is there a way with AngularJS to and get a URL path minus all parameters? I don't want to grab it out of the address bar, I have a var where the value is a URL that I want the path out of.
Turn this: var url1 = http://domain.com/dir1/dir2/?param1=123¶m2=456
Into this: /dir1/dir2/
This just wants to return the path with the parameters:
var justPathLocation = $location.path();
window.location.pathname returns exactly what you need.
On this URL:
http: //stackoverflow.com/questions/30385367/get-location-path-without-parmaters/30386013#30386013?param=value
it returns this:
"/questions/30385367/get-location-path-without-parmaters/30386013"
So it returns only the path name, without query strings or fragment identifiers.
UPDATE
Here's a regex way, it uses the domain name, which you can hard-code or fetch using window.location.hostname:
var url = "http://domain.com/dir1/dir2/?param1=123¶m2=456";
alert(url.match(/http:\/\/domain\.com(.*)\?/)[1]);
And a more generic approach - ^.*\/\/.*?(\/.+)\?:
var url = "http://domain.com/dir1/dir2/?param1=123¶m2=456";
alert(url.match(/^.*\/\/.*?(\/.+)\?/)[1]);
In angularjs, Given a url http://example.com/photos/123 and url template http://example.com/photos/:id (that is used in $resource). How to get the hash: {id: 123}?
All url parameters can be accessed with the $routeParams service:
From the $routeParams documentation:
The route parameters are a combination of $location's search() and path(). The path parameters are extracted when the $route path is matched.
Example:
// Given:
// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
// Route: /Chapter/:chapterId/Section/:sectionId
//
// Then
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
EDIT: Given the below comments, I extend my answer
// The example url you provided.
var url = 'http://example.com/photos/123';
// We get a list with all the parts of the url.
var partList = url.split(/\/|\?|&|=|\./g);
// We get the bit that we know is the photo's id.
var idPart = partList[5];
You would use Angular $routeParams.
For example in your controller:
$routeParams.id
would return '123'
Edit: As pointed out by okigan the default routing assumes you have a location hash so your route would need to be http://example.com/#/photos/123. However you can turn this off to retain your desired routing by turning on html5mode. Please see removing #
Update: You can also access the url parts using regular Javascript. The following would get the second url part.
id = (window.location.pathname).split('/')[2]
You could use this as a base to extend the functionality.
The declaration of the User resource would be something like:
factory('User', function($resource) {
return $resource('/api/user/:userId.json', {}, {
put: {method:'PUT', params: {userId:'#id'}},
});
})
As you can see the -default- parameter for the PUT method is the id attribute within the resource.
if you would like to test:
httpBackend.expectPUT('api/user/1.json').respond(200);
userResource.put();
httpBackend.flush();
I keep getting a failure in the test cause the actual URL that it's being generated is: 'api/user/.json'. The id attribute is not being included in the URL.
It makes sense because I haven't specified the id attribute to the mock object, I didn't because I don't know how to do it.
Thanks in advance.
The path should start with '/', and you need to pass in an ID to make the path match with what is generated in your code. The URL match is string match, so you need to guarantee the URL you expect to hit is exactly same as what is generated.
httpBackend.expectPUT('/api/user/1.json').respond(200);
userResource.put({id:1});
httpBackend.flush();
I am trying to do the following:
http://www.mydomain.com/Foo/json_bar
in my routing file, I want to say anything going to Foo/json_* it should go to the appropriate action in the action.class.php file
ex:
Foo/json_bar1 -> public function executeBar1
Foo/json_bar2 -> public function executeBar2
Thanks
In that case, you could probably write a routing rule like this (untested):
my_rule:
url: /Foo/json_:action/
params: { module: myModule, sf_method: json }
This, because the :action parameter is a "magic" parameter, which sets the action. (Normally you set the action parameter in the params block.
The sf_method is optional, by the way, but it sets the request format as json. That way, any exceptions will also render in JSON, and the correct headers are set for json.
The best practice to do this by the way, would be:
my_rule:
url: /Foo/:action.:sf_method
params: { module: myModule }
In that case you can write a bar1 action. Going to /Foo/bar1.html will render the HTML, and /Foo/bar1.json will render a json response. Of course you're free the replace the :sf_method with json, and set the sf_method param, like in my first example.