Adding a method to Restangular - angularjs

I am new to Restangular. Since its already been used in the project I am currently working on, I need to learn about it. I am trying to setup a new method, which upon called, calls a rest call and return nothing.
for ex: I have factory like this in
//app.js
factory('events', ['Restangular', function (Restangular) {
return Restangular.all('events');
I want to add a method ackAll by extending 'events'. I have tried like this.
RestangularProvider.extendModel('events', function(event) {
event.ackAll = function() {};
return event;
});
I want to call this method whenever user login. I am not sure how to do that. Whatever i tried, i am getting error as "ackAll is not a function ". I am sure I am missing very easy part but I am not sure what it is.

Related

AngularJS 1.5 calling a method from another in component's controller

I am using angularJS 1.5 component in my application. sample code of component's controller as bellow:
function testController()
{
var vm = this;
activate(); // this will be called on first load on component.
vm.testMethod = function ()
{
return "test Method";
}
function activate()
{
console.log(vm.testMethod());
}
when I execute this I am getting error
TypeError: vm.testMethod is not a function.
I know I can create a local function to controller not appending vm., however, in my need, I have a vm.testMethod() used in template to get return some text, which is working properly. e.g.
--template code
{{$ctrl.testMethod()}} // This works properly and display 'test Method' on page.
Due to some reason, I am trying to call vm.testMethod() inside another method e.g. activate(), however getting an error mentioned above?
May I know if am missing anything or trying something which is not possible.
Your issues does not have anything to do with Angular :-)
Your activate function is hoisted because it is a function declaration. That why you can call it "before your wrote it". BUT, vm.testMethod is a function expression and won't get hoisted.
Here is a super simple example that shows the issue your having:
var vm = {};
console.log(vm.hello);
vm.hello = function () {};
console.log(vm.hello);
I would recommend you to read this article for a better understanding of how expressions and declarations work in JavaScript. Also, in order to prevent this from happening again you should follow this advice from John Papa:
Always write function declarations at the bottom of your controller and assign them at the top when you defined your vm variable.

Self Populating AngularJS Factories

I'm looking for some input on exactly how to accomplish the following design pattern.
Background: I have two factories and a controller:
FirstFactory: This is the data storage that contains all the data the application relies on to function
SecondFactory: This is a list of $http.get methods. The getAllCities method just returns a promise
Controller: This is where the data resolves from SecondFactory and then is set into FirstFactory.journey.
Now currently the controller works fine but I am trying to have the data, from SecondFactory.getAllCities() resolve itself in the FirstFactory on runtime instead of waiting for the Controller to update it.
So currently I have a controller that does the following:
build = function() {
return SecondFactory.getAllCities()
.then(function(response) {
FirstFactory.journey = response;
});
};
This works fine and updates the factory with a the data returned from the method SecondFactory.getAllCities(). However I feel that the controller shouldn't be what sets up the default or init data set, I think the factory should accomplish this on it's own.
I assumed, probably incorrectly, that the following would work as instead of doing the call to the SecondFactory inside the controller, I was just moving this call to the FirstFactory so it can resolve itself when its instantiated instead of relying on the controller to populate the FirstFactory.journey with data.
var build;
//This is a call to a factory that contains the data
//I want to grab and store this in my factory on run
build = function() {
SecondFactory.getAllCities()
.then(function(response) {
//Why does this not get returned?
console.log(response);
return response
})
};
//This is the factory object that is returned
return {
journey: build()
}
However the above doesn't work. The console.log in the build function contains the data I require but it isn't being returned by that function. Is this an issue with my implementation of the promise or a broader design pattern issue?

using data from a callback from Ebay api in Angularjs

I am trying to use the ebay api in an angular.js app.
The way the api works by itself is to pass data to a callback function and within that function create a template for display.
The problem that I am having is in adding the data returned from the callback to the $scope. I was not able to post a working example as I didnt want to expose my api key, I am hoping that the code posted in the fiddle will be enough to identify the issue.
eBayApp.controller('FindItemCtrl', function ($scope) {
globalFunc = function(root){
$scope.items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
console.log($scope.items); //this shows the data
}
console.log($scope.items); //this is undefined
})
http://jsfiddle.net/L7fnozuo/
The reason the second instance of $scope.items is undefined, is because it is run before the callback function happens.
The chances are that $scope.items isn't updating in the view either, because Angular doesn't know that it needs to trigger a scope digest.
When you use the Angular provided async APIs ($http, $timeout etc) they have all been written in such a way that they will let Angular know when it needs to update it's views.
In this case, you have a couple of options:
Use the inbuilt $http.jsonp method.
Trigger the digest manually.
Option number 1 is the more sensible approach, but is not always possible if the request is made from someone else's library.
Here's an update to the fiddle which uses $http.jsonp. It should work (but at the moment it's resulting in an error message about your API key).
The key change here is that the request is being made from within Angular using an Angular API rather than from a script tag which Angular knows nothing about.
$http.jsonp(URL)
.success($scope.success)
.error($scope.error);
Option 2 requires you to add the following line to your JSONP callback function:
globalFunc = function(root){
$scope.items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
console.log($scope.items); //this shows the data
$scope.$apply(); // <--
}
This method tells Angular that it needs to update it's views because data might have changed. There's a decent Sitepoint article on understanding this mechanism, if you are interested.

AngularJS $http use data into controller

I'm new in AngularJS so if the question is not 'intelligent' for you, please don't rate it in negative. If someone ask a question, for he isn't stupid.
So..
I would like to use data from an ajax request, like this:
encryptApp.factory('getData', function($http, $rootScope) {
var getData = {};
getData.tot_of = function() {
return $http.get('/path/to').then(function(result) {
return result.data;
});
}
getData.get_info = function() {
return $http.get('/path/to').then(function(result) {
return result.data;
});
}
return getData;
});
In controller I use this:
getData.get_info().then(function(get_info) {
$scope.get_info = get_info;
});
// HERE THE $scope.get_info is UNDEFINED
I'm new in AngularJS and I don't know why does this. So, is there a method that I can use the json data outside the " then function ".
Thanks and please don't rate this question negative. Sorry if my english is not good.
$http.get returns a promise.
By essence, a promise is as Javascript saying:
"Hey ! I let you make the request, but please, I don't want to wait for you, so when you finished, please execute the callback I'm just passing you, since now, I will forget you since I have more code to execute while you're doing your job".
In other words, a promise's callback isn't executed immediately, since the goal is to not block the Javascript "thread" (Javascript is like single-threaded).
So your current code is acting like this:
getData.get_info().then(function(get_info) { //the function inside this "then" IS the callback
$scope.get_info = get_info;
});
// Hey !! The request might not finish ! So don't expect $scope to have the value you expect here !
So the simple example to illustrate would be to imagine that your ajax request takes 100ms to execute.
Within those 100ms, your next Javascript scope is very very very likely to be already reached, having $scope.get_info not initialized yet.
Without promise, your next code, outside of the callback, that should not depend of $scope.get_info, would have to wait 100ms to start, wasting time.
So, is there a method that I can use the json data outside the " then
function ".
There is a way, using broadcasting/emit ($rootScope.$broadcast/$rootScope.$emit) to trigger a corresponding event, but it's often more "anti-KISS" for a simple case.
I advise you to put all your depending code in the promise callback.
To clean your code, merely call a private function that you define outside the callback.

angularjs http.get only works first time

I have a function in my controller that calls an api to retrieve some values:
$scope.Refresh= function(){
$http.get('/get/value')
.success(function(data) {
//some actions
})
.error(function(data) {
//some actions
});
} ;
I want to refresh the values occasionally, so I've done:
setInterval($scope.Refresh, 100000);
I will do in a better way, but now I want to solve this.
but there is a problem:
If, in the controller, I say: $scope.Refresh (to execute the function first time), the controller does nothing.
If I write the same function + setInterval (to test and run it) it works first time (outside the function), but never refresh next times (code function inside), to explain, that execute the function but neither .success nor .error is called.
I have seen the headers with a 304 status (not modified) but the values are modified!!
I tried to disable cache but that did not fix the problem.
I tried to give a random value to the route like: /get/value/(randomNuber) but I get nothing
Where is the problem?
Just running:
$scope.Refresh();
should definitely run the function at least once. If it doesn't something is wrong with your code or with your server route. But you should be getting a console error if that's the case.
For setInterval, you should be using the $interval service that ensures your code is run within the angular loop.
Also, per the documentation, you should explicitly cancel this interval when your controller is destroyed.
var httpInterval = $interval($scope.Refresh, 100000);
$scope.$on('$destroy', function() {
$interval.cancel(httpInterval);
});
I've only had intermittent luck with .success and .error, and I'd like to think that part of it was caching the request. I have very consistent, successful results using .then, as shown:
$scope.Refresh= function(){
var myGet = $http.get('/get/value');
myGet.then(function(data){
//do success things here
}, function(data){
//do error things here
});
};
Other than that, follow the advice that #theJoeBiz gave regarding $interval and you should be fine.

Resources