angularjs this is undefined while using $.proxy - javascript

I have an UserApplications object wich queries the server for a list of applications the user is registered to looking like this:
data.factory('UserApplications', function($resource){
return $resource('/users-rs/api/getapplications/:locale',{},{
query: {method: 'GET', params: {locale: 'locale'}, isArray: true}
});
});
I call it in another service and want to save the data as a JSON string using the angular-localstorageservice module (https://github.com/grevory/angular-local-storage) which is passed to the constructor of the service like this:
function UserService(UserInfoData, localStorageService, UserApplications){
this.UserInfoData = UserInfoData;
this.localStorageService = localStorageService;
this.userApplications = UserApplications;
}
When I give a callback function to the $resource.query() function and wrap it with $.proxy I keep getting this.localstorag is undefined, when I debug it this is a reference to window. So not exactly the behaviour I expected.
Is there any other way to pass 'this' or a reference to the object to the callback function?
I've allready tried with creating a variable with a reference to this but it doesn't do the trick either :/
UserService.prototype.getUserApplications = function(){
var locale = this.getUserinfoLocale();
var applications = this.localStorageService.get(Constants.key_applications+locale);
if(applications !== null){
return JSON.parse(applications);
} else {
return this.userApplications.query({locale: locale}, $.proxy(function(data, locale){
this.localStorageService.add(Constants.key_applications+locale, JSON.stringify(data));
}), this);
}
};

I think you missed the comma position and is sending "this" to userApplications' query method, not jQuery's proxy one.
Try this in your "else" block instead:
return this.userApplications.query({locale: locale}, $.proxy(function(data, locale){
this.localStorageService.add(Constants.key_applications+locale, JSON.stringify(data));
}, this));

Related

manipulate vue.js data parameter from within sub method

I know that I can change the value of a vue data value from within a method by using this.variable_name. But when I'm trying to do this from within a method with a sub-method (because I'm making an ajax request) I am getting an undefined error.
I have something like
var myvue = new Vue({
name: "MyVue",
el: '#my-vue-id',
data: {
fields: field_list // this is set in another js method elsewhere
},
methods: {
reject: function (index, objectid) {
if (confirm("Are you sure?")) {
$.get("/reject/" + objectid, function (data) {
if (data.success == true) {
$("#" + objectid).fadeOut(400, function() {
this.field_list.splice(index, 1);
});
} else {
alert('Failed to delete.');
}
});
}
}
}
});
I also tried setting var self = this; within the $.get method, then trying to splice self.field_list but in both cases I get an error Cannot read property splice of undefined
EDIT since I may have been unclear-- the field_list is being populated. If I were to do this.field_list.splice outside the ajax function, it works fine. The issue is just how to access external scope from with the vue methods.
A callback function does not get your Vue instance as its context (this) when it is called. Use arrow functions for your callbacks, or save this to a variable and use that.
You need to do the var self = this; outside of the $.get method (before it) as within the $.get method you have a different scope, and that is the root of the problem. Then within the $.get method use self.field_list.splice(index, 1);

Where is angular "data" coming from

--- Given this code in a file ---
angular.module('storyCtrl', ['storyService'])
.controller('StoryController', function(Story, socketio) {
var vm = this;
Story.getStory()
.success(function(data) {
vm.stories = data;
});
vm.createStory = function() {
vm.message = '';
var newMessage = vm.storyData.content;
var newStory = { str: newMessage , timeNow: new Date(), mess: "Hello" };
Story.createStory(newStory)
.success(function(data) {
vm.storyData = '';
vm.message = data.message;
});
};
socketio.on('story', function(data) {
vm.stories.push(data);
})
})
Where does "data" being initialize or where is it coming from as it is not even a global variable or from ['storyService'].
Thank you
The variable data represents what the function (getStory or createStory or the on function) is returning to you for use in the function. For example, the getStory function might be returning a json array. Within the success function, this data is assigned to the vm.stories variable.
Does that help?
The storyCtrl module references another module called storyService. Slightly confusing, the storyService module contains a service (or factory) called Story. The Story service provides a method called getStory. Internally getStory very likely makes a call using $http. You can tell because getStory does not use standard promises, but instead uses the success and error methods that $http provides.

nested angular http.get calls

I have a simple angular $http.get, which returns a json object, but I want the id from the json to do another $http.get. I can do this by nesting another $http.get with the first one, but this seems rather stupid. What is the best way to assign the id of the response, data.id, to a variable? I'm having some issues with variable scope; trying to simply assign the value to a variable.
$http.get('/api/v1/foo/userinfo?thunk='+thunk+'&bar='+bar).success(function(data) {
$scope.id = data.id
}).then(function(data){
$scope.id = data.data.id
});
Why don't you watch your variable, in this case $scope.id like this:
$scope.$watch('id', function() {
// Http request goes here
$http.get(...)
});
When you assigned any value to $scope.id your "watch function" will be triggered.
Can use callbacks to make it cleaner. Wrap your call in a function:
function startAJAX(thunk, bar, callback) {
$http.get('/api/v1/foo/userinfo?thunk='+thunk+'&bar='+bar).success(function(data) {
callback(data.id);
});
}
Then make the call and do your next http call:
startAJAX(thunk, bar, function(id) {
$http(id).....
});
});
Using a watch() method isn't necessary. Use callbacks, or if you want to be fancy use promises to keep things organized.
var callOnePromise = $http.get('/api/foo');
var callTwoPromise;
callOnePromise.success(function(data) {
callTwoPromise = $http.get('/api/bar/' + data.id);
});
callTwoPromise.success(function() {
//Cool stuff here.
});

Can't pass around returned object from server

I am picking up a project started by a peer, and having trouble with an API call.
This is my angular controller:
angular.module('oowli').factory('Note', ['$http', function($http) {
var Note = function(data) {
angular.extend(this, data);
};
Note.prototype.save = function() {
var note = this;
return $http.post('/notes', this).then(function(response) {
note = response.data;
}, function(error) {
return error;
});
};
return Note;
}]);
and the call is executed in this function:
var saveNote = function(Note, scope){
return function(span, phrase){
var noteObj = new Note({
user: scope.global.user._id,
content: span.innerText
});
noteObj.save().then(function(){
console.log(noteObj);
});
};
};
problem is, after saving the note, noteObj is the original, not the one that comes back from the server (with an _id field).
Debugging on the Note.prototype.save, response.data comes with the _id;
I need to know how to have access to the returned Note object, in the saveNote function.
You are assigning the new object to the local variable 'note' in the Note.prototype.save function, but then not doing anything with it.
The quickest solution is to copy the properties of the returned object to your note rather than assign to it, so instead of:
note = response.data;
This might work:
angular.copy(response.data, note)
In general though I don't like the approach of having the Note class responsible for saving itself. I would create a note service that saves the object.

Mootools Request.JSON dynamic callback

Developing an app where all tabular data is returned as an object.
Some cells will have onclick events on them.
The JSON object is coming back fine and there is a key in the object call 'cb'.
This is set by the logic on the server.
My question is the object key cb will contain a string, how can I run that as a valid function without using eval()
Example:
var archive = function() {
console.log('archiving');
}
new Request.JSON ({
...
onSuccess: function(r){
//r.cb: 'archive'
docuemnt.id(td).addEvent('click', r.cb);
}
...
});
docuemnt.id(td).addEvent('click', eval(r.cb)); // works looking for alternative
I know i am over thinking this and it should not be that difficult.
Must not have had enough coffee yet today.
Use square bracket notation. If your function is in the global scope, use window[r.cb]:
new Request.JSON ({
...
onSuccess: function(r) {
//r.cb: 'archive'
document.id(td).addEvent('click', window[r.cb]);
}
...
});
If your function is not in the global scope, move your functions into an object:
var callbacks = {
archive: function () { ... },
foo: function () { ... },
...
}
Then use callbacks[r.cb].

Categories