Angular datatables with promise - reload line - javascript

I'm using angular-datatables with promise and everything work's fine. I have a lot of actions that can be done on each register (using angular $http resource) like change a status or something like that.
But, I need to reload datatable's data after every action even if i've edit just one line. And this process get's a little longer!
Is there any way to reload just the data that i've changed? For example, if I edit some line data I want just that line to be reloaded.
Forgive me if that's not a smart question, but I need to know if I can improve the performance of the actions over the table.
Here is my code!
DtOptions
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
vm.defer = $q.defer();
vm.mainService.getItems(idtask, flag, type).then(function(result)
vm.defer.resolve(result.data);
});
return vm.defer.promise;
})
.withOption('headerCallback', function(header) {
if (!vm.headerCompiled) {
vm.headerCompiled = true;
$compile(angular.element(header).contents())($scope);
}
})
.withPaginationType('full_numbers')
.withOption('createdRow', createdRow)
.withOption('deferRender', true)
.withDisplayLength(100)
.withOption('initComplete', function() { });
ReloadData function
function reloadData() {
var resetPaging = false;
vm.dtInstance.reloadData(function callback() {}, resetPaging);
}
After some execution over the table, I call the function reloadData().
Thanks for any help! And I'm sorry for my bad english.

don't reload the page just append the last added data to the array in ng-repeat
with simple javascript push
consider below as array to which we want add last added element. write this in "success block" so if there is confirmation of successful post then this will be added to current stack. same can be done for delete and update.
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi");\

Related

Wait for page load before continuing JavaScript execution

I'm new to JavaScript and trying to get this Tampermonkey script working. The scripts works just fine when it collects data from one page. However, I now want it to collect the data as before, but then move on to another page and continue the data collecting.
My code:
$(document).ready(function() {
$("#getData").click(function() {
// Part 1. Collect data and move on
window.location.href = goToURL;
// Part 2. Collect more data when the page has fully loaded
});
});
I have tired to put Part 2 of the code inside:
setTimeout(function() {
}, 5000);
and
window.onload = function(){
};
But I cannot get the code to work, it either executes before the page has loaded, or seemingly not at all. What am I missing?
When you change page with location.href, your JS is reloaded. So you need a way to store data between page changing. I suggest to use LocalStorage
Your code would look like:
function storeState(state){
localStorage.setItem('state', state);
}
function loadState(state){
return localStorage.getItem('state');
}
$(document).ready(function() {
var state = getState();
$("#getData").click(function() {
// Collect data and put it into state
storeState(/* your collected state*/)
window.location.href = goToURL;
});
});
Notice that you have to do some serialize/deserialize stuff because localStorage only save strings
Also as mentioned #charlietfl if you have different domains it will cause additional difficults

Angularjs click row if the data is available

I'm new to JavaScript so I am not sure what is possible. I am using AngularJS as my frontend application.
I've a clickable table(rows) its pretty much a table inside a table (collapisble table)
I'm trying to click the first row of the table if the data is available so I wrote this function
$scope.clicker = function(){
if (!$scope.first || !$scope.second){
setTimeout($scope.clicker, 500)
}
$(".clickableRow").first().click()
}
This pretty much checks if the values first and second is not null, if not then click the first row. This WOULD work sometimes but almost every time I get this error '
Error: [$rootScope:inprog] $digest already in progress
http://errors.angularjs.org/1.4.3/$rootScope/inprog?p0=%24digest
I am not sure what this means. Any help would be nice.
Using $q.all you can pass in multiple $http requests in an array.
You can use .then on the q.all() method and get a callback when they're all done.
$scope.$watch(
function() {
return $route.current;
},
function(newValue) {
if (newValue) {
$scope.url = newValue.$$route.originalPath;
if($scope.url == '/loadTestForm') return;
$scope.neustaridParam = newValue.params.neustarid;
$q.all([
$http.get('/corecase/browserKPI/'+$scope.neustaridParam).success(function(response){
$scope.browserKPI = response;
}),
$http.get('/corecase/serverKPI/'+$scope.neustaridParam).success(function(response){
$scope.serverKPI = response;
}),
$http.get('/corecase/info/'+$scope.neustaridParam).success(function(response){
$scope.corecaseinfo = response;
})
]).then(function(){
$scope.selectTableRow(0, 1000); //I'd advise not hardcoding the first row's data here. You can do something like this instead: $scope.storeDataModel.storedata[0].id, scope.storeDataModel.storedata[0].storeId
});
}
}
);
If the only purpose behind the click event is to show or hide then you can potentially skip the click event all together. Put a "ng-show" in your tr (or any other element you want to show) and simply set a scoped variable equal to whatever is referencing your data. If you have data then your ng-show will be true and it will show. This is also assuming that your data is undefined or null until it is available, if not just set it to false.
In view:
<tr ng-show="checkData"></tr>
In controller:
$scope.checkData = data;

Appending new results to an open jQuery autocomplete menu

I have an app in which I have multiple search sources. Previously, the users had to choose in what source to search in before searching. If they did not choose, the app would default to one of the options.
However, now they want to search in all the sources at the same time. This is fine enough, but the problem is that when one of the searches returns, it overwrites the previous search result. Pretty much expected behavior. What I basically want is to append the new results to the already open autocomplete menu, instead of overwriting the old results. Naturally, the autocomplete menu would have to empty when it closes.
I guess that this is possible to do, but what approach is the best? I could just have an array I guess, which I append results to and then overwrite _renderMenu to use this array instead of the items one that is passed to the function. Then empty said array at the close event.
Is this the best way to go though? Or is there a more elegant solution?
Some code:
Ok, so searchAction is called by jquery autocomplete eventually. In collection.search I do the ajax call, here the URL is created based in the this parameter, then respondWhithData is called and maps the search result to a proper format (ie value and label for the autocomplete menu). After reponse is called from respondWithData, jquery automagically renders the resultsmenu. Thus, I probably have to overwrite the reponse event function as well as the _renderMenu and possibly _renderItem, yes?
searchAction: function(searchTerm, collection, response){
var self = this;
$.when(collection.search(searchTerm, this)).then(function(data) {
self.respondWithData(data, response);
});
},
respondWithData : function(data, response) {
if (data.length > 0) {
var responseVal = _.map(data, this.mapData);
this.checkResponseCount(responseVal);
response(responseVal);
}
else {
response(this.emptyResult());
}
},
To be clear, the problem is not the multiple search itself, but rendering the asynchronos results. I want to render the first results that come back, and then appends the rest as soon as they are returned from the server.
Edit 2:
Just tried to edit ui.content in the autocompleteresponse event, but any edit does not take once it renders for some reason...
Edit 3: Ah, ui.content can only be modified directly, not changed. If I push every single change instead of concating two arrays ui.content shows what I want.
It works I guess, but its not perfect.
I can figure how looks your scenario but I'm guessing:
You should have like:
function search1() {
$.ajax({ ...
success: function(data) {
$('#myResultsDiv").html(data)
}
});
}
etc
Instead of overwritting the #myResultsDiv you need to Append the results like:
function search1() {
$.ajax({ ...
success: function(data) {
$('#myResultsDiv").append(data)
}
});
}
Edit: You can also do something like this:
var resultsArray = [];
var searchDone = 0;
var totalSearchs = 5; //assuming 5 searches
function search1() {
function search1() {
$.ajax({ ...
success: function(data) {
//APPEND data to resultsArray
searchDone++;
if(searchDone==totalSearch) //syncronize the 5 searchs before render
renderSearchs(resultsArray);
}
});
}

AngularJS Data One Step Behind

I'm tracking map coordinates using angularJS to update the data, however I've run into an odd issue where the data you see on the screen does not match the console statement.
zombie.controller("move", function($scope) {
io.on("location", function(data) {
console.log(data);
$scope.location = data.loc;
})
$scope.move = function(direction) {
$scope.title = ": Traveling";
io.emit("move", {direction:direction});
}
});
The console will log something like: Object {loc: "(59,30)"}
Let's assume the previous data was Object {loc: "(60,31)"}. My page will print (60,31) when the console is logging (59,30).
Also, when the page loads, the initial click will not display anything, but the console will log the correct data.
I have tried moving io.on('location') around inside the angular function, but if it's inside move() it will go bonkers and log like 15 times in a row and lag out. Outside the function is fine except for this issue. Any thoughts?
The code inside the io.on("location") is initiated by socket.io and Angular doesn't know about it, so its changes to the scope are not reflected until the next digest cycle. That is likely why the screen updates are always one step behind. Use $scope.$apply() to force a digest...
io.on("location", function(data) {
console.log(data);
$scope.location = data.loc;
$scope.$apply();
})
I agree with above answer but still in some cases like on input of text box,
you need to give timer to digest it properly.
setTimeout(function(){
$scope.apply();
}, 50);
This solves my problem.

Access a parameter in Javascript

i've a strange problem with JS (probably a noob bug), but i'm stuck with it
In function fillInVersionsList, if i put an alert("tempo") or a break in firebug, i can access to my datas in parameter (ie : alert(pSimulator.simulatorData['LastVersion']) and i've the right result. The problem is that if i don't put an alert/firebug break before my access to datas, i've a JS error pSimulator.simulatorData is undefined.
$(document).ready(function() {
var simulator = new Simulator();
// Load SimulatorData into the simulator class
initSimulatorData(simulator);
// Fill in datas into VersionsList (2nd arg = Id of the list)
fillInVersionsList(simulator, $('#VersionsList'));
});
function initSimulatorData(pSimulator)
{
$.ajax({
url: "getData.php?action=init",
success: function(data) {
pSimulator.initSimulatorData(data);
}
});
}
function fillInVersionsList(pSimulator, pSelect)
{
//alert("tempo");
alert(pSimulator.simulatorData['LastVersion']);
pSelect.html('<option>test</option>')
}
function Simulator()
{
var simulatorData;
this.initSimulatorData = function(pSimulatorData)
{
this.simulatorData = pSimulatorData;
}
}
Is there something to solve this problem?
Thanks in advance
I suspect initSimulatorData is loading some data asynchronously.
Adding the alert gives it long enough for the data to be loaded.
You will need to add some sort of callback function, eg:
initSimulatorData(simulator, function () {
// Fill in datas into VersionsList (2nd arg = Id of the list)
fillInVersionsList(simulator, $('#VersionsList'));
});
Whats looks like from your problem is that simulator is taking time to initialize and when fillInVersionsList is called pSimulator is still not completely initalized.
When you put an alert it is getting some time delay by which time simulator is initalized.
Check if there is any callback method after simulator is completely initialized and then call fillInVersionsList method after that.
what does initSimulatorData(simulator) does? Is there any asynchronous code invloved in this?

Categories