Pass parameter to async request in indexeddb - promise

I have the next code:
$.get('Lubricantes/getListaEquipos', function (data) {
if (data.length > 0) {
var peticion = base_datos_local.transaction(['Equipos'], 'readwrite').objectStore('Equipos').clear();
total_equipos = data.length;
peticion.onerror = function () {
console.log('No se pudo limpiar el maestro de equipos.');
};
peticion.onsuccess = function (e) {
for (var i = 0; i < data.length; i++) {
var peticion = base_datos_local.transaction(['Equipos'], 'readwrite').objectStore('Equipos').add(data[i]);
peticion.onerror = function (e) {
console.log('No se pudo cargar el equipo' + i);
};
peticion.onsuccess = function (e) {
console.log('Equipo ' + i + ' agregado');
};
}
};
}
});
When this execute the var i don't exist, how can pass to add method the value of i?

Async is fun, isn't it?
I'll save you the lecture on scopes and variable references and just recommend that you just wrap the guts of your for loop into an "immediately invoked anonymous function" like so:
$.get('Lubricantes/getListaEquipos', function (data) {
if (data.length > 0) {
var peticion = base_datos_local.transaction(['Equipos'], 'readwrite').objectStore('Equipos').clear();
total_equipos = data.length;
peticion.onerror = function () {
console.log('No se pudo limpiar el maestro de equipos.');
};
peticion.onsuccess = function (e) {
for (var i = 0; i < data.length; i++) {
(function(entrada, j) {
var peticion = base_datos_local.transaction(['Equipos'], 'readwrite').objectStore('Equipos').add(entrada);
peticion.onerror = function (e) {
console.log('No se pudo cargar el equipo' + j);
};
peticion.onsuccess = function (e) {
console.log('Equipo ' + j + ' agregado');
};
})(data[i], i);
}
};
}
});
data[i] is evaluated immediately and passed in as an argument to this closure, so you'll have the correct reference in scope when the callbacks eventually fire.

Related

do nested loops in Casperjs

I am new in Casperjs and I would like do dinamic testing depending on external data sources. But, I am experiencing some problems with the loops.
This is my code:
var url = ['http://google.com/','http://www.as.com'];
casper.test.begin('PruebaLoop', function (test) {
casper.start('about:blank',function() {
});
casper.then(function() {
casper.viewport(1024, 768);
//casper.echo(casper.getTitle());
});
console.log('url.length: ' + url.length)
for (i = 0; i < url.length; i++) {
casper.thenOpen(url[i], function() { // open that link
console.log('i: '+i);
});
casper.wait(5000, function() {
this.echo("I've waited for a 5 seconds.");
});
casper.then(function() {
casper.capture('url'+i+'.png');
});
}
casper.run(function() {
casper.echo('Test completado');
casper.test.done();
});
});
From debugging, I always get 2 as the result. I don't know why. Could you please offer me some help?
Thanks a lot!
my solution is:
var urls = ['http://www.elpais.es','http://www.as.com'];
casper.test.begin('PruebaLoop', function (test) {
casper.start('auto:blank',function() {
console.log("-----------------------------------");
console.log("estoy en start ");
});
casper.then(function() {
casper.viewport(1024, 768);
console.log("estoy en wiewport");
console.log("urls.length = " + urls.length);
console.log("-----------------------------------");
});
for(i = 0; i < urls.length; i++) {
(function(index) {
var url = urls[index]
casper.thenOpen(url, function() {
console.log('index tiene el valor: '+ index);
console.log('i tiene el valor: '+ i);
});
casper.then(function() {
this.wait(5000);
console.log("estoy en wait: "+ index);
});
casper.then(function() {
this.wait(5000);
casper.capture("pagina"+index+".png");
console.log("estoy en capture: " + index);
console.log("-----------------------------------");
});
})(i);
}
casper.run(function() {
casper.echo('Test completado');
casper.test.done();
});
});
it works.

Where to declare response.success()/response.error() in my cloud code

Hi while I run this Job in Cloud code I get an error log:
Failed with: success/error was not called. Define functions working good, but in Job logs I have this error log. Please assist me to solve the issue
Parse.Cloud.job("JobSchedule", function (request, response) {
var Group = Parse.Object.extend("Group");
var query = new Parse.Query(Group);
query.equalTo("JobScheduled", true);
query.find({
success: function (results) {
for (var i = 0; i < results.length; ++i) {
var created = new Date(results[i].createdAt);
var current = new Date();
var timeDiff = Math.abs(current.getTime() - created.getTime());
var horsDiff = timeDiff / (60 * 60 * 1000);
if (horsDiff >= parseInt(results[i].get("JobHours"))) {
results[i].set("JobScheduled", false);
results[i].set("GroupType", "Private");
results[i].set("JobHours", 0);
results[i].save();
var GroupMembers = Parse.Object.extend("GroupMembers");
var query1 = new Parse.Query(GroupMembers);
query1.equalTo("GroupId", results[i].id);
query1.find({
success: function (grpresults) {
for (var j = 0; j < grpresults.length; ++j) {
grpresults[j].set("GroupType", "Private");
grpresults[j].save();
}
},
error: function (error) {
response.error(error);
}
});
}
}
},
error: function (error) {
response.error(error);
}
});
});
In each of your success scenarios, you need to call response.success(), where between the parenthesis you can return a status message, such as
response.success('Hello world did work');
In your case, this would probably go here:
Parse.Cloud.job("JobSchedule", function (request, response) {
var Group = Parse.Object.extend("Group");
var query = new Parse.Query(Group);
query.equalTo("JobScheduled", true);
query.find({
success: function (results) {
for (var i = 0; i < results.length; ++i) {
var created = new Date(results[i].createdAt);
var current = new Date();
var timeDiff = Math.abs(current.getTime() - created.getTime());
var horsDiff = timeDiff / (60 * 60 * 1000);
if (horsDiff >= parseInt(results[i].get("JobHours"))) {
results[i].set("JobScheduled", false);
results[i].set("GroupType", "Private");
results[i].set("JobHours", 0);
results[i].save();
var GroupMembers = Parse.Object.extend("GroupMembers");
var query1 = new Parse.Query(GroupMembers);
query1.equalTo("GroupId", results[i].id);
query1.find({
success: function (grpresults) {
for (var j = 0; j < grpresults.length; ++j) {
grpresults[j].set("GroupType", "Private");
grpresults[j].save();
}
// HERE IS THE NEW CODE
response.success("Saved objects properly");
},
error: function (error) {
response.error(error);
}
});
}
}
error: function (error) {
response.error(error);
}
});
});

Saving a Parse object within a for loop does save all the objects

I have the following code where I am trying to save personalities of a movie. Only few personalities get created and saved.
var query = new Parse.Query(Movie);
query.find({ success: function(movies) {
console.log("movies.length " + movies.length );
for (var movieIterator = 0; movieIterator < movies.length ; movieIterator++) {
cast_array = movies[movieIterator].get("cast");
console.log(cast_array);
for (var i = 0; i < cast_array.length; i++) {
var personalityObj = new Personality();
personalityObj.set('name', cast_array[i].trim());
personalityObj.save(); // NOt all personalities get saved
}
}
response.success("Awesome");
}, error: function(error) {
response.error(error)
}});
How may I improve the code so that all the personalities get stored/saved in the DB.
Can you try this and let me know if it works.
var query = new Parse.Query(Movie);
query.find({ success: function(movies) {
console.log("movies.length " + movies.length );
var list = [];
for (var i = 0; i < movies.length ; i++) {
cast_array = movies[i].get("cast");
console.log(cast_array);
for (var j = 0; j < cast_array.length;j++) {
var personalityObj = new Personality();
personalityObj.set('name', cast_array[j].trim());
list.push(personalityObj);
}
}
Parse.Object.saveAll(list).then(function(results){
console.log("Objects were saved!");
response.success("Awesome");
},function(eerror){
console.log(eerror);
response.error(eerror);
});
}, error: function(error) {
response.error(error);
}});
The above code is using saveAll function for batch operation. Docs

Resize image and upload in couchdb or upload url blob to couchdb

I need to upload attached resized images into a couchdb doc. Right now I'm not resizing images, only uploading them by using the following code:
function attachFile(event) {
event.preventDefault();
var form_data = {};
$("form.attach-file :file").each(function() {
form_data[this.name] = this.value;
});
if (!form_data._attachments || form_data._attachments.length == 0) {
alert("Please select a file to upload.");
return;
}
var id = $("#ant-show").data("doc")._id;
$(this).ajaxSubmit({
url: "db/" + $.couch.encodeDocId(id),
success: function(resp) {
$('#modal-attach').modal("hide");
helios_link(id);
}
});
}
The code I'm using to rezise images, but that doesn't work to upload them, is the following:
function attachFile(event) {
function isImage (str) {
return str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
}
function resizeAndUpload(file, callback, progress)
{
var reader = new FileReader();
reader.onloadend = function() {
var tempImg = new Image();
tempImg.onload = function() {
var MAX_WIDTH = 500;
var MAX_HEIGHT = 500;
var tempW = tempImg.width;
var tempH = tempImg.height;
if (tempW > tempH) {
if (tempW > MAX_WIDTH) {
tempH *= MAX_WIDTH / tempW;
tempW = MAX_WIDTH;
}
} else {
if (tempH > MAX_HEIGHT) {
tempW *= MAX_HEIGHT / tempH;
tempH = MAX_HEIGHT;
}
}
var resizedCanvas = document.createElement('canvas');
resizedCanvas.width = tempW;
resizedCanvas.height = tempH;
var ctx = resizedCanvas.getContext("2d");
ctx.drawImage(this, 0, 0, tempW, tempH);
var dataURL = resizedCanvas.toDataURL("image/jpeg");
var file = dataURLtoBlob(dataURL);
var fd = $("#upload");
fd.append("_attachments", file);
var id = $("#ant-show").data("doc")._id;
console.log(fd);
fd.ajaxSubmit({
url: "db/" + $.couch.encodeDocId(id),
success: function(resp) {
$('#modal-attach').modal("hide");
helios_link(id);
}
});
};
tempImg.src = reader.result;
}
reader.readAsDataURL(file);
}
function dataURLtoBlob(dataURL) {
// Decodifica dataURL
var binary = atob(dataURL.split(',')[1]);
// Se transfiere a un array de 8-bit unsigned
var array = [];
var length = binary.length;
for(var i = 0; i < length; i++) {
array.push(binary.charCodeAt(i));
}
// Retorna el objeto Blob
return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
}
function uploaded(response) {
// Código siguiente a la subida
}
function progressBar(percent) {
// Código durante la subida
}
event.preventDefault();
console.clear();
var files = document.getElementById('_attachments').files;
console.log(files);
resizeAndUpload(files[0], uploaded, progressBar);
}
Do anybody know how can I improve my code to make it work? I would like to have in fact two different solutions, one that helps me to improve my code and the second one, to get instructions on how to upload a URL BLOB as attachments into a couchdb document.

SlickGrid filter not working

I am fairly new to SlickGrid. I am trying to make SlickGrid filter work but no luck. I am following the example (http://mleibman.github.io/SlickGrid/examples/example4-model.html).
Below is my source code.
$(document).ready(function() {
var tName;
$('#submit').click(function(e) {
tName = $('#source option:selected').text();// name1
tName = tName.trim();
$.ajax({
url : 'someUrl',
type : 'GET',
cache : false,
success : function(d) {
var grid;
var searchString = "";
var data = [];
var columns = new Array();
var cols = d[0].columns;
var pkColNames = d[0].pkColNames;
for (var j=0; j< cols.length; j++) {
var key = {id: cols[j].colName, name: cols[j].colName, field: cols[j].colName, width: 200, sortable:true, editor: Slick.Editors.LongText};
columns[j] = key;
}
var options = {
editable: true,
enableAddRow: false,
enableCellNavigation: true,
asyncEditorLoading: false,
enableColumnReorder:true,
multiColumnSort: false,
autoEdit: false,
autoHeight: false
};
function myFilter(item, args) {
return true;// Let us return true all time ?
}
for (var i = 0; i < d.length; i++) {
var tempData = (data[i] = {});
var title = null;
var val = null;
for (var q = 0; q < d[i].columns.length; q++) {
title = d[i].columns[q].colName;
val = d[i].columns[q].colValue;
tempData[title] = val;
}
}
var dataView = new Slick.Data.DataView({ inlineFilters: true });
grid = new Slick.Grid("#myGrid", dataView, columns, options);
dataView.setPagingOptions({
pageSize: 25
});
var pager = new Slick.Controls.Pager(dataView, grid, $("#myPager"));
var columnpicker = new Slick.Controls.ColumnPicker(columns, grid, options);
grid.setSelectionModel(new Slick.CellSelectionModel());
grid.onAddNewRow.subscribe(function(e, args) {
// Adding a new record is not yet decided.
});
grid.onCellChange.subscribe(function (e) {
var editedCellNo = arguments[1].cell;
var editedColName = grid.getColumns()[editedCellNo].field;
var newUpdatedValue= arguments[1].item[grid.getColumns()[editedCellNo].field];
var editedColType = "";
for (var cnt = 0; cnt < cols.length; cnt++) {
if (editedColName == cols[cnt].colName) {
editedColType = cols[cnt].colType;
break;
}
}
var pkKeyValue="";
for (var v=0; v <pkColNames.length;v++) {
for (var p=0; p<grid.getColumns().length; p++) {
if (pkColNames[v] == grid.getColumns()[p].field) {
var value = arguments[1].item[grid.getColumns()[p].field];
pkKeyValue += "{"+pkColNames[v] + '~' +getColDbType(grid.getColumns()[p].field) + ":"+value+"},";
break;
}
}
}
function getColDbType(colName) {
for (var c = 0; c < cols.length; c++) {
if (colName == cols[c].colName) {
return cols[c].colType;
}
}
}
pkKeyValue = pkKeyValue.substring(0, pkKeyValue.length-1);
$.ajax({
url: 'anotherUrl',
type:'GET',
dataType:'text',
success: function(f) {
bootbox.alert("Data updated successfully");
},
error: function() {
bootbox.alert("Error - updating data. Please ensure you are adding the data in right format.");
grid.invalidateAllRows();
grid.render();
}
});
});
grid.onClick.subscribe(function (e) {
//do-nothing
});
dataView.onRowsChanged.subscribe(function(e, args) {
grid.updateRowCount();
grid.invalidateRows(args.rows);
grid.render();
});
grid.onSort.subscribe(function(e, args) {
// args.multiColumnSort indicates whether or not this is a multi-column sort.
// If it is, args.sortCols will have an array of {sortCol:..., sortAsc:...} objects.
// If not, the sort column and direction will be in args.sortCol & args.sortAsc.
// We'll use a simple comparer function here.
var comparer = function(a, b) {
return a[args.sortCol.field] > b[args.sortCol.field];
}
// Delegate the sorting to DataView.
// This will fire the change events and update the grid.
dataView.sort(comparer, args.sortAsc);
});
// wire up the search textbox to apply the filter to the model
$("#txtSearch").keyup(function (e) {
console.log('Called...txtSearch');
Slick.GlobalEditorLock.cancelCurrentEdit();
// clear on Esc
if (e.which == 27) {
this.value = "";
}
searchString = this.value;
updateFilter();
});
function updateFilter() {
console.log("updateFilter");
dataView.setFilterArgs({
searchString: searchString
});
dataView.refresh();
}
dataView.beginUpdate();
dataView.setItems(data, pkColNames);
dataView.setFilterArgs({
searchString: searchString
});
dataView.setFilter(myFilter);
dataView.endUpdate();
},
error : function() {
bootbox.alert("Invalid user");
}
});
});
});
Your function myFilter() is always returning true so of course it will never work. The example that you looked at, was to filter something specific. I would recommend that you look at the following example to have a generic filter. From the example, simply type the text you are looking on a chosen column and look at the result... see example below (from SlickGrid examples).Using fixed header row for quick filters
In case you want a more in depth conditional filters ( > 10, <> 10, etc...), please take a look at my previous answer on how to make this kind of filtering possible, see my previous answer below:SlickGrid column type
Hope that helps you out

Resources