I have some data in a IndexedDB table that quite simply contains this data:
var Customers = [
{ ssn: "123-45-6666", name: "Andrew", age: 22, email: "andrew#hotmail.com" },
{ ssn: "555-66-7777", name: "Gail", age: 25, email: "gail#email.me" }
];
I then have this function to get data back from the IndexedDB:
function RetrieveTableRows(Table) {
var returnData = [];
var db = window.indexedDB.db;
var trans = db.transaction([Table], "readwrite");
var store = trans.objectStore(Table);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onerror = window.indexedDB.onerror;
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false) {
return;
}
returnData.push(result.value);
result.continue();
};
return returnData;
}
I realise that it does not work because the onsuccess function is asynchronous, however I can't my head around a solution.
Simply, I want to be able to write:
var myCustomers = RetrieveTableRows('customers');
and be able to then use the variable myCustomers - is this possible?
I have tried using JQuery.deferred(); method but that didn't seem to work, and I know that I could possibly do something like this:
transaction.oncomplete = function() {
ReturnTableRows(returnData);
};
}
function ReturnTableRows(data) {
//do something with the array of data
}
but I can't work out how to pass this back to the myCustomers variable.
Using the deferred object you should be able to do something like this
function RetrieveTableRows(Table) {
var returnData = [];
//setup deferred object
var defer = $.Deferred();
var db = window.indexedDB.db;
var trans = db.transaction([Table], "readwrite");
var store = trans.objectStore(Table);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onerror = window.indexedDB.onerror;
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false) {
//when done resolve the promise, you could also do more
//checking and reject the data so you can handle
//errors
defer.resolve(returnData);
//Make sure we exit the function once we run out of data!
return
}
returnData.push(result.value);
result.continue();
};
//return the promise
return defer.promise();
}
//########### then to use this ###########
//this is now a promise
var myCustomersPromise = RetrieveTableRows('customers');
var myCustomers;
//action todo when promise is resolved/rejected
$.when(myCustomersPromise ).done(function(data){
//do something with the data/assign it to you var here
myCustomers= data;
}).fail(function(data){
});
although i have not actually used indexedDB before so maybe misunderstanding how the query knows it is finished ( I am asssuming result.continue() called the onSuccess again and the result is false when it has gone through all the data) but this is the setup I use when doing anything asynchronously in my apps
An alternate method I've found that uses less code, is a lot simpler and doesn't require JQuery.
Setup:
// Create the function(s) to grab and store the data
var myCustomers;
var getData = {
customers: function(data) {
myCustomers = data
}
}
Call:
//Send the callback function we want into the retrieve function
trans.oncomplete = function (e) {
RetrieveTableRows('Customers', getData.customers)
};
Function:
function RetrieveTableRows(Table, Callback) {
var returnData = [];
var db = window.indexedDB.db;
var trans = db.transaction([Table], "readwrite");
var store = trans.objectStore(Table);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onerror = window.indexedDB.onerror;
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false) {
// Send the information back to our specified function
Callback(returnData);
return
}
returnData.push(result.value);
result.continue();
};
}
Related
I have these employee information which display if you click on the employee box. But sometimes the value of some fields returns null even if they have a value but when I retry it will return ok. Is this some code problem? here is my code...
First I store the elements into an object
var uamnumber = $(this).find(".box-list-agents-uamnumber").text();
var agentInfo = $(this).find(".box-list-agents-info").text().split("/");
var agentElement = {
txtUam: $("#search-txt-uam-number"),
txtFirstName: $("#search-txt-first-name"),
txtMiddleName: $("#search-txt-middle-name"),
txtLastName: $("#search-txt-last-name"),
txtContactNumber: $("#search-txt-contact-number"),
txtEmailAddress: $("#search-txt-email-address"),
txtClassification: $("#search-txt-classification"),
txtAgentStatus: $("#search-txt-agent-status"),
txtReasonResignation: $("#search-txt-reason-resignation"),
txtCsp: $("#search-txt-csp-name"),
txtProgramId: $("#search-txt-program-name"),
txtSite: $("#search-txt-site-name"),
txtBirthDate: $("#search-txt-birth-date"),
txtLiveDate: $("#search-txt-live-date"),
txtEndDate: $("#search-txt-end-date"),
txtProgram: $("#search-program-name")
};
var agentParam = {
uam: uamnumber,
csp: agentInfo[0],
program: agentInfo[1]
}
Dashboard_GetAgentInfo(agentParam, agentElement);
$("#search-well-tool-access").hide();
$("#search-well-agent-info").fadeIn();
and here is the function that has been called.
function Dashboard_GetAgentInfo(agentInfo,agentElement) {
$.ajax({
type: "POST",
url: "IROA_StoredProcedures.asmx/Dashboard_GetAgentInfo",
data: JSON.stringify(agentInfo),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var uamdetails = response.d;
var appendItem = "";
$.each(uamdetails, function (index, Dashboard_GetAgentInfoInfo) {
var uamnumber = Dashboard_GetAgentInfoInfo.uamnumber;
var firstname = Dashboard_GetAgentInfoInfo.firstname;
var middlename = Dashboard_GetAgentInfoInfo.middlename;
var lastname = Dashboard_GetAgentInfoInfo.lastname;
var contactnumber = Dashboard_GetAgentInfoInfo.contactnumber;
var emailaddress = Dashboard_GetAgentInfoInfo.emailaddress;
var csp = Dashboard_GetAgentInfoInfo.csp;
var cspid = Dashboard_GetAgentInfoInfo.cspid;
var program = Dashboard_GetAgentInfoInfo.program;
var programid = Dashboard_GetAgentInfoInfo.programid;
var site = Dashboard_GetAgentInfoInfo.site;
var siteid = Dashboard_GetAgentInfoInfo.siteid;
var birthdate = Dashboard_GetAgentInfoInfo.birthdate;
var livedate = Dashboard_GetAgentInfoInfo.livedate;
var enddate = Dashboard_GetAgentInfoInfo.enddate;
var classification = Dashboard_GetAgentInfoInfo.classification;
var agentStatus = Dashboard_GetAgentInfoInfo.agentstatus;
var reasonResignation = Dashboard_GetAgentInfoInfo.reasonresignation;
$(agentElement.txtUam).val(uamnumber);
$(agentElement.txtFirstName).val(firstname);
$(agentElement.txtMiddleName).val(middlename);
$(agentElement.txtLastName).val(lastname);
$(agentElement.txtContactNumber).val(contactnumber);
$(agentElement.txtEmailAddress).val(emailaddress);
$(agentElement.txtClassification).val(classification);
$(agentElement.txtAgentStatus).val(agentStatus);
$(agentElement.txtReasonResignation).val(reasonResignation);
$(agentElement.txtCsp).val(cspid)
$(agentElement.txtProgramId).val(programid);
$(agentElement.txtSite).val(siteid);
$(agentElement.txtBirthDate).val(birthdate);
$(agentElement.txtLiveDate).val(livedate);
$(agentElement.txtEndDate).val(enddate);
$(agentElement.txtProgram).text(program);
NumbersOnly();
});
},
error: function (XMLhttpRequest) {
alert("error in Dashboard_GetAgentInfo");
console.log(XMLhttpRequest);
}
});
}
and this is the web service that has been called
public List<Dashboard_GetAgentInfoDetails> Dashboard_GetAgentInfo(string uam, int csp, int program) /*int CSP, int Program*/
{
DataTable table = null;
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "[Dashboard_GetAgentInfo]";
cmd.Parameters.AddWithValue("#uam", uam);
cmd.Parameters.AddWithValue("#csp", csp);
cmd.Parameters.AddWithValue("#program", program);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
table = this.dbConn.ExecuteDataTable(cmd);
Dashboard_GetAgentInfo_Details.Clear();
foreach (DataRow row in table.Rows)
{
Dashboard_GetAgentInfoDetails _list = new Dashboard_GetAgentInfoDetails();
_list.uamnumber = row["UAM #"].ToString();
_list.firstname = row["First Name"].ToString();
_list.middlename = row["Middle Name"].ToString();
_list.lastname = row["Last Name"].ToString();
_list.contactnumber = row["Contact Number"].ToString();
_list.emailaddress = row["Email Address"].ToString();
_list.csp = row["CSP"].ToString();
_list.cspid = Convert.ToInt32(row["CSPID"].ToString());
_list.program = row["Program"].ToString();
_list.programid = Convert.ToInt32(row["ProgramID"].ToString());
_list.site = row["Site"].ToString();
_list.siteid = Convert.ToInt32(row["SiteID"].ToString());
_list.birthdate = row["BirthDate"].ToString();
_list.livedate = row["LiveDate"].ToString();
_list.enddate = row["EndDate"].ToString();
_list.classification = Convert.ToInt32(row["Classification"].ToString());
_list.agentstatus = row["Agent Status"].ToString();
_list.reasonresignation = row["Reason Resignation"].ToString();
Dashboard_GetAgentInfo_Details.Add(_list);
}
return Dashboard_GetAgentInfo_Details;
}
does storing elements into an object and passing it as a parameter is a good practice of coding? and what may be the cause of the select having no value even if I when I try to console.log the value and it returns ok?
I think the problem is here:
$(agentElement.txtUam).val(uamnumber);
$(agentElement.txtFirstName).val(firstname);
...
You should do:
agentElement.txtUam.val(uamnumber);
agentElement.txtFirstName.val(firstname);
...
There is no need to use jquery selector $, because agentElement.txtUam is already one, also gathering elements inside an object is a best practice because you can't pass each one as a parameter.
The perfect answer to this is add a call back function so the dropbox have a option first before adding the val. Here is the idea of adding a callback function
function Filtering_GetSite(siteElement, callback) {
if (typeof (callBack) == "function") {
callBack();
}
}
the line checking of the callback parameter is to ensure that it its a function before executing so you can call the function like this Filtering_GetSite(sample) insted of Filtering_GetSite(sample,function(){}) when omiting the callback function
I have browsed this site looking for clues to help solve this problem but they were not specific enough to help solve it.
I have this login code that has a nested function that I need to call from another function which is outside the scope of the login script.
jstore.plugins.login = function(url, options) {
var login = jstore.plugins.login;
var opts = $.extend(true, {}, jstore.plugins.login.defaults, options);
var server = jstore.url2server({ url: url });
return this.each(function() {
var $this = $(this);
var id = jstore.uid();
$this.append('<div class=\'jstore_widget jstore_login\' id=\'' + id + '\'></div>');
var updated = function(server) {
var element = document.getElementById(id);
if(element) {
var e = $(element);
var loginDisplayed = $('.jstore_login_name', element).length == 1;
if (server.loggedIn() === false && loginDisplayed) {
return true;
}
e.html(login.getHTML(server, opts));
if(server.loggedIn()) {
e.click(function() {
var server = jstore.getServer(url);
if(server && server.loggedIn()) {
server.logout();
}
});
I need to call this part from somewhere else:
e.click(function() {
var server = jstore.getServer(url);
if(server && server.loggedIn()) {
server.logout();}
Based on research from this site; I tried to call it directly by constructing the following line but it doesn't work:
jstore.plugins.login.updated().e.click();
I have little practical knowledge of jQuery. Keeping in mind that I am a novice; syntactically, what is the proper way to call a nested javascript function from a location outside the scope of its parent function?
Regards.
:::::::::::::UPDATE::::::::::::::
I was able to get this to work, many thanks to nuway for his excellent suggestion and others for their constructive criticism.
Here is what I ended up with:
jstore.plugins.login = function(url, options) {
var login = jstore.plugins.login;
var opts = $.extend(true, {}, jstore.plugins.login.defaults, options);
var server = jstore.url2server({ url: url });
return this.each(function() {
var $this = $(this);
var id = jstore.uid();
$this.append('<div class=\'jstore_widget jstore_login\' id=\'' + id + '\'></div>');
window.onClick = function() {
var server = jstore.getServer(url);
if(server && server.loggedIn()) {
server.logout();
}
};
var updated = function(server) {
var element = document.getElementById(id);
if(element) {
var e = $(element);
var loginDisplayed = $('.jstore_login_name', element).length == 1;
if (server.loggedIn() === false && loginDisplayed) {
return true;
}
e.html(login.getHTML(server, opts));
if(server.loggedIn()) {
e.click(onClick);
}
I just needed to globalize the onClick function with window.onClick = ... in order to call it from another function.
why not put this block into its own function such as
var onClick = function() {
var server = jstore.getServer(url);
if(server && server.loggedIn()) {
server.logout();
}
}
and then you can just pass it in as such:
e.click(onClick)
and you can invoke it from somethere else by simply calling onClick()
I'm trying to run save() on a retrieved _User object, but it doesn't seems to save the field I've modified ("ignoredUsers"), which is an array. Although I can see that the save actually went through, as updatedAt does change.
Here is the code:
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", userid1);
query.first({
success: function(result){
var ignored = result.get("ignoredUsers");
if (!ignored) {
ignored = [];
}
ignored.push(userid2);
result.set("ignoredUsers", ignored);
result.save();
}
});
function appendUser(toUser, userId) {
return toUser.fetch({
success: function(user) {
var ignored = user.get("ignoredUsers");
if (!ignored) {
ignored = [];
}
ignored.push(userId);
user.set("ignoredUsers", ignored);
user.save();
}
});
}
Parse.Cloud.job("ignoredUsers", function(request, status) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query("Conversation");
return query.each(function(conversation) {
var participants = conversation.get("participants");
var userid1 = participants[0].id;
var userid2 = participants[1].id;
var user1 = participants[0];
var user2 = participants[1];
return appendUser(user1, userid2).then(function() {
return appendUser(user2, userid1); });
});
status.success();
});
The problem was that the cloud function returned before waiting for the callbacks to finish
i need to used instant variable inside the object define function like that .
i need to use Result variable outside the function
function Request(params,type,url){
var loginReq = Titanium.Network.createHTTPClient();
loginReq.open(type,url);
loginReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
loginReq.setRequestHeader("enctype", "multipart/form-data");
loginReq.setRequestHeader("Content-Type", "image/png;charset=utf-8");
loginReq.send(params);
loginReq.onload = function()
{
var json = this.responseText;
var Result = JSON.parse(json);
};
return Result;
};
exports.Request = Request;
i need to return Result Or use it outside the scope.
You need to use either a callback, or a promise library
Using a callback
function Request(params,type,url,callback){
//...
loginReq.onload = function() {
var json = this.responseText;
var Result = JSON.parse(json);
callback(Result);
};
};
//Somewhere else
Request(/**/,/**/,/**/,function(result){
//use result
});
Using a promise library like Q
var Q = require("q");
function Request(params,type,url,callback){
var deferred = Q.defer();
//...
loginReq.onload = function() {
var json = this.responseText;
var Result = JSON.parse(json);
deferred.resolve(Result);
};
return deferred.promise;
};
//Somewhere else
Request(/**/,/**/,/**/).then(function(result){
//use result
});
I'm writing a jQuery plugin for work which pulls in RSS feed data using Google's Feed API. Using this API, I'm saving all of the relevant RSS feed data into an object, then manipulating it through methods. I have a function which is supposed to render the RSS feed onto the webpage. Unfortunately, when I try to display the individual RSS feed entries, I get an error. Here's my relevant code:
var RSSFeed = function(feedTitle, feedUrl, options) {
/*
* An object to encapsulate a Google Feed API request.
*/
// Variables
this.description = "";
this.entries = [];
this.feedUrl = feedUrl;
this.link = "";
this.title = feedTitle;
this.options = $.extend({
ssl : true,
limit : 4,
key : null,
feedTemplate : '<article class="rss-feed"><h2>{title}</h1><ul>{entries}</ul></article>',
entryTemplate : '<li><h3>{title}</h3><p>by: {author} # {publishedDate}</p><p>{contentSnippet}</p></li>',
outputMode : "json"
}, options || {});
this.sendFeedRequest = function() {
/*
* Makes the AJAX call to the provided requestUrl
*/
var self = this;
$.getJSON(this.encodeRequest(), function(data) {
// Save the data in a temporary object
var responseDataFeed = data.responseData.feed;
// Now load the data into the RSSFeed object
self.description = responseDataFeed.description;
self.link = responseDataFeed.link;
self.entries = responseDataFeed.entries;
});
};
this.display = function(jQuerySelector) {
/*
* Displays the RSSFeed onto the webpage
* Each RSSEntry will be displayed wrapped in the RSSFeed's template HTML
* The template markup can be specified in the options
*/
var self = this;
console.log(self);
console.log(self.entries);
};
};
$.rssObj = function(newTitle, newUrl, options) {
return new RSSFeed(newTitle, newUrl, options);
};
// Code to call the jquery plugin, would normally be found in an index.html file
rss = $.rssObj("Gizmodo", "http://feeds.gawker.com/Gizmodo/full");
rss.sendFeedRequest();
rss.display($('div#feed'));
Obviously, my display() function isn't complete yet, but it serves as a good example. The first console.log() will write all of the relevant data to the console, including the entries array. However, when I try to log the entries array by itself, it's returning an empty array. Any idea why that is?
I guess the problem is that display() is called without waiting for the AJAX request to complete. So the request is still running while you already try to access entries - hence the empty array.
In order to solve this you could move the call to display() into the callback of $.getJSON(). You just have to add the required selector as a parameter:
this.sendFeedRequest = function(selector) {
var self = this;
$.getJSON(this.encodeRequest(), function(data) {
var responseDataFeed = data.responseData.feed;
...
self.entries = responseDataFeed.entries;
self.display(selector);
});
};
EDIT:
If you don't want to move display() into the callback, you could try something like this (untested!):
var RSSFeed = function(feedTitle, feedUrl, options) {
...
this.loading = false;
this.selector = null;
this.sendFeedRequest = function() {
var self = this;
self.loading = true;
$.getJSON(this.encodeRequest(), function(data) {
...
self.loading = false;
if (self.selector != null) {
self.display(self.selector);
}
});
};
this.display = function(jQuerySelector) {
var self = this;
if (self.loading) {
self.selector = jQuerySelector;
}
else {
...
}
};
};