ng-table , getData called more than once, why? - angularjs

For some reason when getData uses angular resource to bring the data it is being called twice, causing the resource to do it REST request twice too <--- bad...
Any idea why and how to solve it?
Here a working testcase/plunker example that recreates this scenario (look at the browser console - "getData being called...." displayed twice ) b.t.w as you can see I'm not really using the resource to bring real data, just to demonstrate the scenario, In my real app I do use the resource to bring real data and its being called twice just like in this example,
Thanks ahead
After looking into the src of the ng-table I noticed the following
$scope.$watch('params.$params', function(params) {
$scope.params.settings().$scope = $scope;
$scope.params.reload();
}, true);
Which means that the tables calls it 'getData' on count/filter/group/groupBy/page/sorting
which explains the behavior I was seeing.

When you call params.count(...) you ask ng-table to refresh data as you change page size. That's why you have two get-data calls.
If you don't want to have paging, then remove calls params.count and params.total.
If you need paging, then set page size and do not change it in getData.

This happened to me with a weird reason. getData get called twice on init (first load) only. changing page or sorting didn't call getData twice. The reason was that at init the ng-table directive was hidden in the template file.

Thank #Alexander Vasilyev. I understood my problem as you said. I want to explain a litte more here. In fact, the object "params" is the object configuration the table ng-table, then if "params" changed (ex: count or a property of the object), ng-table will invoke function getData() to refresh table.
In my case, I want to get information in the object "params" and change it but I dont want to refresh ng-table. I did it by cloning object "params" et work his object copied. Clone the object in JS with jQuery :
var resultParams = jQuery.extend(true, {}, params.$params);
And then, I will work on the object resultParams instead of "params" original.

Related

How to call angularjs function while adding data to a json array?

As I have mentioned in this question, I have a function that returns a different text based on an input.
This is working fine when I use it in static text areas, like below:
<td>{{('input_text'|fnName:dataObject:'query_param')}}</td>
How can I call this function while I am assigning data to a json object? Originally the input_text is added to the json, but I need to run a lookup and replace the text.
EDIT: The json object is assigned to a dropdown, but I doubt if I will be able to call my function in the dropdown attributes.
p.s. The content in dataObject could change while using the application; so the function should be invoked with the latest data.
Try setting the filter's $stateful property to true.
https://stackoverflow.com/a/35563980/4028303
This should make the filter re-run upon digest cycles, even if the left-side data being passed in hasn't changed.

AngularJs Restangular get in interval

I must check data in API every for example 5sec and pass to array which is binding to html. When I invoke function in $interval like this:
$interval(refreshData, 5000);
It works, but destroy any other action which I doing for example close dropdowns etc.
What is the best way for create GET in specific interval?
I saw that in Firefox is ok, only Google Chrome,cancel any actions like coil selected dropdown list etc. when I load data to variable in promise. Anyone have idea why it happen?

Binding not updating, ocModal

I'm using the ocModal directive + service (https://github.com/ocombe/ocModal). When someone wants to delete a record they click the delete button which pops up, via ocModal, a modal to confirm.
oc-modal-close ng-click="deleteNote(id)"
So far so good. Within the controller deleteNote runs. Console.log shows the argument is the id I passed. I call an API to delete the note from my database and on a success call a function to delete the note from the Angular variable $scope.notes.
$scope.removeNote = function(id){
console.log(id);
console.log($scope.notes);
delete $scope.notes[id];
console.log($scope.notes);
};
The id is correct and the $scope.notes after the delete command shows it was correctly deleted. Yet, there is no corresponding update on my front-end. Following advise I've seen on Stackover I used apply() which led to a 'digest cycle already in progress' error. I then tried to use $timeout but while that got rid of the digest cycle error, it didn't solve the problem of the bind.
Is it relevant that the $scope.notes is used by a ng-repeat that then uses a directive? I've experimented a bit and don't think so, but just in case wanted to mention it.
Where are you calling $scope.removeNote from? Is it from your main controller or in the modal's controller? maybe a directive?
It feels like it is hitting the wrong scope. You can try to move notes to $scope.model.notes and see if it helps, as it will ensure the correct scope is referenced, but it's hard to say unless you try and provide a fiddle with the issue occurring.
I've created this simple fiddle trying to mimic an API call with $timeout and it works -> http://jsfiddle.net/7eqsc/1/
angular.module('myApp',[])
.controller('myCtrl',function($scope,$timeout){
$scope.notes={
a:'AngularJS',
b:'Rocks'
}
$scope.addRandom=function(){
$scope.notes[parseInt(Math.random()*10000).toString(36)]='New Item';
}
$scope.removeNote=function(id){
//emulate API call
$timeout(function(){
delete $scope.notes[id];
},2000);
}
});
In general, I recommend placing things under an object, such as ".model.yourArray", it ensures references are kept correctly and will save you a lot of trouble.

How to use $resource in AngularJS properly for building a client app?

I've been following this tutorial http://draptik.github.io/blog/2013/07/28/restful-crud-with-angularjs/. I implemented a Grails backend with it instead of the Java one in the tutorial.
I've got the data coming back and forth, with one issue. If I create/update/delete a user, I don't see the changes reflected on my user list when I am redirected back. I have to refresh the page to see the updates.
Looking at the network traffic for an edit, it looks like it does a PUT and fires off the GET before the PUT is complete. Assuming this is because $resource returns a promise so things can be done asynchronously. So how do I handle this so that when $location redirects me, my list is up to date?
I'm guessing the options are to wait for the PUT to complete before redirecting/querying for the list, or to somehow manually manage the $scope.users to match the request?
Or maybe this tutorial is just a bad example? Maybe there is a better way to do it (still using $resource)?
Note: I've seen Restangular out there, and I've seen $http with success callbacks, but I would like to understand the situation above.
One way to overcome this issue would be to not redirect to the list page, till you get a callback, and then do a redirect. You can show some busy indicator till that time. The resource call looks like this.
resource.update(config,data,function() { //gets called on success},
function(error) { //gets called on failure});
In real life scenario waiting for the response of update makes sense as you want to handle the error and success scenarios on the same page.
I don't see your code anywhere so i'm just assuming (based on what you wrote and your current problem)
You are probably doing a full (or partial) get each time you changed a user and (re)binding the result to your scope. Doing this in the callback of the resource should actually start the digest cycle angular does to update modified objects. If you had been doing the fetching outside $resource - for example with custom/jquery ajax you would need to execute $scope.$apply()
What i really don't understand you would need to wait for the callback. You already know you added/modified a user. Instead of 'detaching' that user from your scope, modify it, post it to your rest server, then wait for callback, and reinserting it into the scope - why not modify it directly in the list/array you put on your scope?
var users = Users.get(function () {
$scope.users = users.record; // bind the resulting records to the scope
});
$scope.updateUser = function (user) {
resource.update(...); //pseudo
};
Then in your html, you will keep a reference to the currentUser and the div-list will update automaticly.
<div ng-repeat="user in users" ng-click="currentUser=user">{{user.Name}}</div>
<input ng-model="currentUser.Name">
<button ng-click="updateUser(currentUser);">Update</button>
If you don't want to see the update in the list while you type, but only once your callback fires or when you hit the button, would would instead use another ng-model for your input like this:
<input ng-model="tempUser.Name">
And you would then copy the value other in either the updateUser method or in the resource callback like this:
$scope.updateUser = function (user) {
user.Name = $scope.tempUser.Name; // should update automaticly
resource.update(...) // pseudo
}
Hope it helped!

ExtJs determine visibility on form load

In Extjs 3.4 I have a fairly large form that is being populated from an ajax call via someForm.getForm().load({url: someplace, etc}) which is working flawlessly. The problem I can't seem to get around though, is that there are several comboboxes and checkboxes that determine if another field is visible and allowBlank.
As per the answer on a similar question I have tried using the actioncomplete event on the form but the fields do not have values at that point. I've also tried using the success event of the load() call but get the same issue.
Is there any other ways of getting this functionality from the form.load() call?
Edit - here is my load call:
var panel = Ext.getCmp('someFormID');
panel.getForm().load({
method: 'GET',
url: 'ajax_get_request.aspx?id=' + id,
success: function (form) {
// This will error: object is null or undefined
alert(form.findField('fieldID').getValue());
}
});
I'm relatively new to Extjs so maybe I'm just missing something here...
Not sure why hooking into success callback of Ext.form.BasicForm.load() fails for you, but I can propose an alternative approach.
I usually use explicit Ext.Ajax.request() call to load data into Ext.data.Record. Then in request()'s success callback I load data into form using Ext.form.BasicForm.loadRecord(). If you need to act upon loaded values, you can do it in the same callback.
I do it this way, because I like to have original values from the server stored somewhere aside.

Resources