restangular PUT ignoring ID param - angularjs

So I have the following angular 1.3 code
Restangular.one('user',270).get().then(function(existingUser){
existingUser.password = "foo";
existingUser.put();
});
Which grabs the user at http://api.dev/user/270 fine, however, the existingUser.put(); makes a PUT request to http://api.dev/user, ignoring the ID.
Changing to
Restangular.one('user/270').get().then(function(existingUser){
existingUser.password = "foo";
existingUser.put();
});
works fine, however looking at the examples on the Restangular homepage, it appears my original code should also work fine. Any pointers to whats going wrong?

Solved, issue was related to the existingUser being returned having a existingUser.userID attribute rather than a existingUser.id attribute.
Its this attribute that restangular seems to use for future post/put requests, rather than the id passed into the one() command.

Related

Getting the Angular Typeahead to work with JSONP and JSON with properties

I've been pulling my hair out trying to get the $http.json() to properly return a result set of objects. I have locally stored examples of the same response and they work fine.
Can anyone look at this code and tell me what I'm doing wrong? It has to do with returning $http or something in that bit.
Demo: http://plnkr.co/edit/x325wZ4mwi9DNM8tAxgH?p=preview
You seem to have changed your plunker. The first one where you were using $http.jsonp call seems close but with CORs issues it is hard to test - you should definitely check the encoding type of your JSONP returned data is correct. However...
I would structure the $http.get as per the code below. Now that you have dropped $http.jsonp in favour of $http.get, also note that you may now need to explicitly unpack the returned JSON data string into a javascript object via jsonDecode. Lastly you will likely have to unwrap your server response to return just the json payload with no JSON_CALLBACK() wrapper.
var url = 'http://sitesbyjoe.com/angular-tests/typeahead/schools.php?callback=JSON_CALLBACK'
$http.get(url).success(function(data) {
console.log(data);
$scope.schools = angular.jsonDecode(data);
});

Restangular put loses part of the url

I want to modify one object via a REST API using Restangular on the client side. I do the following:
Restangular.setBaseUrl('/api/v1');
return Restangular.one('lists', item.listId).one('items',item.order).get().then(function(elem) {
elem.text = item.text;
elem.put();
});
But the put method gets the wrong URL missing the ID for the last member (item.order).
The expected url is /lists/2/items/22 but i get /lists/2/items and the PUT fails.
What could I be doing wrong?
Ok, let me try a theory :)
My comment above was a bit lame because I was focusing on the first part of the code and not the put().
The first part is perfect, you tell Restangular to build the URL with one() methods and the GET request must be very fine.
Then, base on a new Restangular-aware object, you try to persist the change in your API.
However, I believe that Restangular does not actually know what field to use as id in order to build the right query for your elem object.
Did you try to configure, in your Restangular Entity Provider the fields property?
RestangularProvider.setRestangularFields({
id: "orderId",
});
I believe that specifying the right field as id would suffice.
As a bonus, it seems that .save() will use PUT or POST accordingly if it's a new object or not.
Hope this helps

DnnModuleAuthorize Attribute Always Returns Unauthorized in Web API

I'm trying to use this attribute on methods in the web API for a custom module:
[DnnModuleAuthorize(AccessLevel = DotNetNuke.Security.SecurityAccessLevel.Edit)]
but no matter what SecurityAccessLevel I set, I always get a 401 unauthorized response.
I was able to make the code work by adding:
[AllowAnonymous]
on the method, and adding:
if (!ModulePermissionController.CanEditModuleContent(this.ActiveModule))
return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "You do not have permission to access this content.");
to the beginning of my method, but it seems like this is a workaround that I really shouldn't need because it's exactly what that attribute is there for. I'm running DNN 7.2.1.
Anyone have any idea where I'm going wrong with the attribute?
Turns out it was actually related to the anti-forgery token. I'm using Angular so I'm setting my headers manually in my Angular service rather than using the built-in ServicesFramework setModuleHeaders method and was only setting the TabId and ModuleId. I didn't think the [AllowAnonymous] attribute would override the anti-forgery stuff but it looks like it definitely does (which is good to know).
Full solution for those doing the same:
var baseUrl = sf.getServiceRoot('[yourmodulename]') + '[controller]';
var config = {
headers: {
'ModuleId': sf.getModuleId(),
'TabId': sf.getTabId(),
'RequestVerificationToken': sf.getAntiForgeryValue()
}
};
Do you have the SupportedModules attribute applied to your controller (or action method)? If so, I'd guess there's a mismatch between the name you're passing in there and the real name in DNN (you should be passing in the desktop module name). Try removing that attribute and seeing if it helps.
The same process that sets ActiveModule and the current user (and would thus make your check in the action method work) should be responsible for implementing the DnnModuleAuthorize attribute's check. So, that's definitely perplexing. Maybe that changed, and if you just pass ModuleId but not TabId in the headers, then it sets ActiveModule, but won't authenticate?
Have you looked at the traffic in Fiddler and made sure that the ModuleId and TabId headers are being sent correctly? Does being logged in as a super-user (i.e. host-level user) affect any of the auth checks (if so, perhaps the URL isn't being constructed properly, and DNN is identifying the wrong portal)?
When you initialize the ServicesFramework, make sure you do it inside a document.ready function.
var self = {};
jQuery(document).ready(function ($) {
self.sf = $.ServicesFramework(<%=ModuleID %>);
});
More info: www.dnnsoftware.com/forums/threadid/507753/scope/posts/services-framework-problems

How to return/edit REST resource with AngularJS & Restangular

Using Restangular for AngularJS, keep getting an object object from Mongolab.
I'm sure it has to do with Promise but not sure how to use/implement this coming from old Java OO experience.
(Side note, would something like Eloquent Javascript, some book or resource help me understand the 'new' Javascript style?)
The small web app is for Disabled Students and is to input/edit the students, update the time they spend after school and then output reports for their parents/caregivers every week.
Here's the code that returns undefined when popping up a new form (AngularJS Boostrap UI modal)
I personally think Restangular & the documentation is a great addition so hope it doesn't dissuade others - this is just me not knowing enough.
Thanks in advance
app.js
...
$scope.editStudent = function(id) {
$scope.myStudent = Restangular.one("students", id);
console.log($scope.myStudent);
}
I'm the creator of Restangular :). Maybe I can help you a bit with this.
So, first thing you need to do is to configure the baseUrl for Restangular. For MongoLab you usually do have a base url that's similar to all of them.
Once you got that working, you need to check the format of the response:
If your response is wrapped in another object or envelope, you need to "unwrap" it in your responseExtractor. For that, check out https://github.com/mgonto/restangular#my-response-is-actually-wrapped-with-some-metadata-how-do-i-get-the-data-in-that-case
Once you got that OK, you can start doing requests.
All Restangular requests return a Promise. Angular's templates are able to handle Promises and they're able to show the promise result in the HTML. So, if the promise isn't yet solved, it shows nothing and once you get the data from the server, it's shown in the template.
If what you want to do is to edit the object you get and then do a put, in that case, you cannot work with the promise, as you need to change values.
If that's the case, you need to assign the result of the promise to a $scope variable.
For that, you can do:
Restangular.one("students", id).get().then(function(serverStudent) {
$scope.myStudent = serverStudent;
});
This way, once the server returns the student, you'll assign this to the scope variable.
Hope this helps! Otherwise comment me here!
Also check out this example with MongoLab maybe it'll help you :)
http://plnkr.co/edit/d6yDka?p=preview

Why is angularFire example deleting all of my Firebase entries?

I'm trying to get a simple angularFire example working, and am seeing anything I add to my synced Firebase db being immediately deleted. I expected the input box to sync to a string in /items/foo. What am I missing?
angularFire is a little aggressive about removing items that don't match the expected data type. There's discussion about fixing this behavior on Github if you're interested, but you can work around it by explicitly specifying the data type using the 4th argument:
var url = 'https://andreystest.firebaseio.com/items';
angularFire(url, $scope, 'items', '');
The fourth argument is an empty string, which tells angularFire that whatever is stored at the URL is a string. The default model type is an array ([]).
Edit: There seems to be some issues with jsFiddle and Angular. You are missing the ng-app and ng-controller directives which means angular is never initialized. However, even after adding those tags I can't get it to work in jsFiddle, it does work on a regular web page though. Give http://misc.firebase.com/~anant/angular-test.html a try!

Resources