AngularJS : run function after scope has been loaded with data from DB - angularjs

So i am currently running into this problem
I have select options which value are retrieved from DB. I use ui-router, and in the controller i always set if(vm.action == 'blabla') then it will call a function then retrieve the data from the webservice.
The problem is, when I am calling more than 2 data(example products and tax select choices). How can i run a function after particular select options has been successfully retrieved from DB?
Take an example, i am doing quotation to invoice module. There are tax and products. These 2 retrieved from DB. in the ajax call after I retrieved the products succesfully, I directly run another function that will calculate all the prices and tax. But somehow, the tax has not been successfully loaded into vm.options.tax after all the products have been loaded successfully
I have tried using $scope.watch('vm.options.tax',function()) but it just gives me undefined in the first place and didn't update me once the vm.options.tax has been loaded with data from DB.
how can i 'wait' for the vm.options.tax has been loaded and then run the function?
Thank you

When you're using scope.watch, it will triggered once the dom first fully loaded and when the model value changed. When the dom is load, the process of retrieving data from db isn't finish, that's why you get undefined value. You can use angular promise. The semantics of Angular dictate that you use promises as a sort of 'callback handle' - do something asynchronous in a service, return a promise, and when the asynchronous work is done, the promise's then function is triggered.
var populateTax = function() {
return $http.get('/api/get_all_tax')
.then(
function (response) {
// Calculate pricing here
var pricing = response.data * tax;
},
function (httpError) {
// translate the error
throw httpError.status + " : " +
httpError.data;
});
};

Related

how to check multiple responses simultanously

$scope.placeOrder = function() {
var callbackBalance = apiService.updateBalance($scope.order);
callbackBalance.then(function(data) {
if(data.data.success) {
var callback = apiService.createOrder($scope.order);
callback.then(function(data){
if(data.data.success)
{
localStorageService.cookie.clearAll();
alert("Order Placed Successfully");
$state.go("createOrder");
}
else
alert('Sorry! Cannot place order');
});
}
else
{
alert('Cannot update company balance')
}
});
This a code to place order for a company and update its balance amount according to the order total.The code works fine but according to this code first the balance amount API is called and once its response is success order API will be called and its response will be checked.But, how can we check if both are successful then only update databases for balance and order.Right now a case can be that balance is updated for a company but for some reason no order was placed.
I am using MEAN stack for my development.
You can use $q service from angular
A service that helps you run functions asynchronously, and use their
return values (or exceptions) when they are done processing. You can
create a request object like this
You can create request array and pass it to $a.all function.
var request = [apiService.updateBalance($scope.order), apiService.createOrder($scope.order)]
and use $q.all function to get provided request simultaneously
$q.all(request).then(function (response) {
}, function (error) {
});
that will get the request data simultaneously. Make sure to add $q as dependency.

In AngularFire how to keep track of data is "In flight"?

I'm working on chatting application in firebase and angular. When I send message using $scope.send(message) function it's directly upend to $scope.messages array because of three-way binding of angularfire. It's initially stored in locally and sync with server in background. I want to keep track message's status if it's sync with server or not. AngularFire's $push method has callback when it's sync with server. But I'm getting no clue of how to keep track of data is "In flight" ( Not synched with server but added in angular scope variable.)
var Ref = new Firebase('FIREBASE_APP_URL');
var ref = Ref.child('messages');
$scope.messages= $firebaseArray(ref).orderByChild('createdAt').limitToLast(10));
$scope.send = function(message) {
$scope.messages.$add(message).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
console.log($scope.messages.$indexFor(id)); // returns location in the array
});
}
The $firebaseArray object is not involved in any three-way data binding. That is limited to $firebaseObjects .bindTo() method.
What happens when you call $add() is that a local child_added event is immediately raised and the $firebaseArray updates its internal data based on that. This is how all Firebase clients work, not just AngularFire, and it is part of why Firebase appears to work instantaneous.
If you want to know when the item was added on the server, you can use the promise that $add() returns. When that promise resolves, the data has been committed on the server.
From the AngularFire documentation for $add():
This method returns a promise which is resolved after data has been saved to the server.
var list = $firebaseArray(ref);
list.$add({ foo: "bar" }).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
list.$indexFor(id); // returns location in the array
});

NodeJS update user status dynamically with Angular

I have this little issue. I have a service that has a Subscription option. When an item in the DataBase is modified (i.e. customer order), I want the customer to see the change in real-time.
Once the user logs in, he is automatically subscribed to his order's status (or several orders, as the case may be). When the status changes, the service sends a POST to a URL that I designate and when that is done, I want to change the client's order status, however I have no idea how to modify Angular's model in order to change what the user sees.
module.exports = function (app) {
app.route('/api/machine')
.post(function (req, res) {
console.log(JSON.stringify(req.body));
return res.send("post returned " + JSON.stringify(req.body));
})
};
At the moment, I get the updates from the Service and print them out, but how do I update the view as well?
try use $watch() function.. when the value is modified, the view is updated.
$scope.$watch(function(scope) { return scope.data.myVar },
function(newValue, oldValue) {
document.getElementById("").innerHTML =
"" + newValue + "";
}
);
I dont know how you've constructed this project's structure, but if you're using a API, use http post to notify your front when changes are done.
the digest or watch, will make your controller do a function always the value has changed.
Angular Digest,Watch and Apply docs.
i hope this helps.
cya.

Angular caching returned data from HTTP call not functioning properly

I have this snippet below in my controller:
var cache = $cacheFactory('contacts');
var data = cache.get('contacts');
if(!data) {
Contacts.get()
.success(function(result) {
data = result;
cache.put('contacts', data);
});
}
My Contacts.get() call returns 152KB of data and is taking ~1.5s to run. I'm trying to cache this data since it does not need to be up to date.
However, every time I refresh the HTTP call is still being made and i'm seeing undefined in the console from logging cache.get('contacts') and data.
How can I cache this data returned from the HTTP call and reference it in the scope?
How does your data looks like ? In case it's a json object, just try to stringify it before caching it, something like
cache.put('contacts', JSON.stringify(data));
---- UPDATE ----
You can't use $cacheFactory to persist data.
$cacheFactory does not persist over sessions and should only used for in-session persistency, what you're looking for is localStorage. there are a lot of good libraries for easily integrating localStorage with angular (for instance https://github.com/grevory/angular-local-storage)

TVRage consume service via AngularJS

i am trying to consume this webservice (http://services.tvrage.com/feeds/show_list.php) from TVRage using Angularjs.
I can 'connect' to the service (using firebug I see GET show_list.php STATUS 200 OK) but when i try to print any data from the response I get none.
This is the code that i use:
var TV_Episodes = angular.module('TV_Episodes', ['ngResource']);
TV_Episodes.controller('GetAllEpisodes', function($scope, $resource) {
var dataService = $resource('http://services.tvrage.com/feeds/show_list.php');
$scope.data = dataService.get();
console.log($scope.data());
});
any ideas on how I can just console.log the the response?
UPDATE 1:
After some more trying i found out that that i get the following error as a response from TVRAGE.
"XMLHttpRequest cannot load http://services.tvrage.com/feeds/show_list.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access."
therefor i tweaked my code so
var dataService = $resource('http://services.tvrage.com/feeds/show_list.php?key=xxxx',{},{headers: { 'Access-Control-Allow-Origin': '*' }});
but i still get the same error as before.
$resource.get() returns a promise, which means you are likely printing to the console prior to the data being retrieved. Instead use the appropriate callback function:
$scope.data = dataService.get(function() { console.log($scope.data); });
The get method is asyncronous. When it is called it returns immediately with a reference to an object (or array, if specified - but not a promise as indicated in MWay's answer). Then, later, that same reference is updated with the data that is returned from the server on success. Here's the relevant part from the documentation:
It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data. This is a useful trick since usually the resource is assigned to a model which is then rendered by the view. Having an empty object results in no rendering, once the data arrives from the server then the object is populated with the data and the view automatically re-renders itself showing the new data. This means that in most cases one never has to write a callback function for the action methods.
As fast as the request might be, it won't resolve until the event loop comes around again. The resource is helpfully designed to free you up from having to worry about writing callbacks. If you need to though, the get method takes callback function parameters that will be invoked when the request resolves and the data is ready.
var TV_Episodes = angular.module('TV_Episodes', ['ngResource']);
TV_Episodes.controller('GetAllEpisodes', function($scope, $resource) {
var dataService = $resource('http://services.tvrage.com/feeds/show_list.php');
$scope.data = dataService.get(function () {
console.log($scope.data());
});
});
Or, you can access the promise used for processing the request by using *$promise", which is a property on empty instance object returned from get.

Resources