With JQuery, I'm loading a set of postcode data via a json call, which is loaded once on document load to populate an option select. I can do that within the one function and it's fine.
However, every time the user selects a different postcode in the select, the code is fired (via .change), and I'm required to load the (quite large) same json data again to populate some different fields.
Because the first call is contained in the callback function, the data never gets outside that scope, and can't be reused again.
If someone changes the items 100 times, that's 100 times the data gets loaded, which seems wasteful, and slow.
Is there any way to call that data once, and have it available to the global/wider scope so it's accessible to the .change function?
EDIT Here's the code:
$(document).ready(function() {
GetPostcodes();
$("#postcodes").change(function() {
console.log("Selection Changed to " + $(this).val());
});
});
function GetPostcodes() {
$.getJSON("population.json", function(cases) {
var filtercases = $(cases).filter(function(i, n) {
return n.POA_NAME16 >= "2450" && n.POA_NAME16 <= "2489"
});
var postcodes = [];
$.each(filtercases, function(i, n) {
postcodes.push(n);
});
postcodes = postcodes.unique();
postcodes = postcodes.sort();
var options = [];
for (var i = 0; i < postcodes.length; i++) {
options.push('<option value="',
postcodes[i].POA_NAME16, '">',
postcodes[i].POA_NAME16, '</option>');
}
$("#postcodes").html(options.join(''));
});
}
Here's what the JSON looks like:
{
"POA_NAME16": 2000,
"Combined": "BARANGAROO,DARLING HARBOUR,,DAWES POINT,HAYMARKET,MILLERS POINT,PARLIAMENT HOUSE,SYDNEY,SYDNEY SOUTH,THE ROCKS",
"Tot_p_p": 27411
},
{
"POA_NAME16": 2006,
"Combined": "THE UNIVERSITY OF SYDNEY",
"Tot_p_p": 1259
},
So while I'm only using the postcode data in the first call to populate the drop down box, I'd like to be able to access all the information for when the .change property is fired to show the other information.
Cheers
I think the problem has come that I've tried to do this:
GetPostcodes();
console.log(the global variable I set)
which doesn't work.
But if I don't reference that global variable until another event, everything's in there and working - so although I already had the answer - your help pushed me to look further in. Cheers :P
Related
I'm trying to allow non-signed in users the ability to add items to a basket.
When the button is clicked the code below is run.
By default the basket value doesn't exist, so the if statement should create a value.
The else statement will add 1 to existing value.
This seems to cause an infinite loop and the number in the database jumps to 1016.
I've probably approached this in the wrong way and can't see how to stop this.
function addToBasket(sessionID){
firebase.database().ref('tempUser/' + sessionID).on('value', function (snapshot) {
var data = snapshot.val();
if (data == null) {
//update
firebase.database().ref('tempUser/' + sessionID).set({
basket: 1,
});
}
else {
//get basket number
var currentBasket = Object.values(data);
//turn string into a integer
let number = parseFloat(currentBasket) ;
//add one to the value
var newNumber = number + 1;
//upload new number to db
firebase.database().ref('tempUser/' + sessionID).set({
basket: newNumber,
});
}
});
}
Thank you in advance for any help or advice,
Connor
You're attaching a permanent listener to tempUser/$sessionID in your database. This means that Firebase immediately calls your callback method with the current value in the database, and then calls the same callback each time the value changes.
Since inside this call, you are changing the data with tempUser/$sessionID, that triggers the same callback again. Which then makes another change to tempUser/$sessionID, which triggers the callback again. And again, and again...
If you only want to change the value once, use once() instead of on():
firebase.database().ref('tempUser/' + sessionID).once('value', ...
I'm using API Jira
I'm doing some functions but before to use function, I need to verified if a value exist or not
If he exists so I can launch functions else do nothing.
I'm doing this :
// Call the file functions.js
var functions = require('./functions.js')
/*
Function getAllIssueForSCII displays all the issues in the form of a JSON and that browses all the keys that are in the SCII project
Function pushInitialization initializes the computer score card to 80 on Jira
*/
functions.getAllIssueForSCII().then(function(json){
for (let i=0; i<json.issues.length;i++){
if(json.issues[i].fields.customfield_14038 = null){ // i'm doing this
console.log(json.issues[i].key);
functions.pushInitialization(json.issues[i].key);
}
}
});
/*
A delay is added so that Jira can correctly recover the value 80.
Thanks to this value, we can do all the calculation (Function calculate)
Function pushComputerScoreCard push the final value into the computer score card.
Function generateJSON generates a JSON.
Function replaceCharacter solve the problem of array inside the JSON
*/
setTimeout(function() {
functions.getAllIssueForSCII().then(function(json){
for (let i=0; i<json.issues.length;i++){
functions.calculate(json.issues[i]);
functions.pushComputerScoreCard(json.issues[i].key);
functions.generateJSON(json.issues[i].key);
functions.replaceCharacter();
}
});
}, 1000)
My problem: After the settimeout, he recover value already exist and do the calcul...
I need to verified my condition in all of the script .
Thanks for your help
You are assigning null value in an if condition:
if(json.issues[i].fields.customfield_14038 = null){ // i'm doing this
You need to compare values:
if(json.issues[i].fields.customfield_14038 === null){ // You need to do this:
I have a list containing folders, and I'm trying to get the count of the total number of files in these folders.
I manage to retrieve a ListItemCollection containing my folders. Then it starts being... picky.
ctx is my ClientContext, and collection my ListItemCollection.
function countFiles()
{
var enumCollection = collection.getEnumerator();
while(enumCollection.moveNext())
{
currentItem = enumCollection.get_current();
var folder = currentItem.get_folder();
if (folder === 'undefined')
return;
ctx.load(folder, 'ItemCount');
ctx.executeQueryAsync(Function.createDelegate(this, function()
{
totalCount += folder.get_itemCount();
}), Function.createDelegate(this, onQueryFailed));
}
}
So it works... half of the time. If I have 6 items in my collection, I get 3 or 4 "The property or field 'ItemCount' has not been initialized" exceptions, and obviously my totalCount is wrong. I just can't seem to understand why, since the executeQueryAsync should not happen before the folder is actually loaded.
I'm very new to Javascript, so it may look horrid and be missing some essential code I didn't consider worthy of interest, feel free to ask if it is so.
Referencing closure variables (like folder in this case) from an asynchronous callback is generally a big problem. Thankfully it's easy to fix:
function countFiles()
{
function itemCounter(folder) {
return function() { totalCount += folder.get_itemCount(); };
}
var enumCollection = collection.getEnumerator();
while(enumCollection.moveNext())
{
var folder = enumCollection.getCurrent().get_folder();
if (folder === undefined) // not a string!
return;
ctx.load(folder, 'ItemCount');
ctx.executeQueryAsync(itemCounter(folder), Function.createDelegate(this, onQueryFailed));
}
}
(You don't need that .createDelegate() call because the function doesn't need this.)
Now, after that, you face the problem of knowing when that counter has been finally updated. Those asynchronous callbacks will eventually finish, but when? You could keep a separate counter, one for each query you start, and then decrement that in the callback. When it drops back to zero, then you'll know you're done.
Since SP.ClientContext.executeQueryAsync is an async function it is likely that the loop could be terminated before the first call to callback function completes, so the behavior of specified code could be unexpected.
Instead, i would recommend another and more clean approach for counting files (including files located under nested folders) using SharePoint JSOM.
How to count the total number of files in List using JSOM
The following function allows to count the number of list items in List:
function getItemsCount(listTitle, complete){
var ctx = SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle(listTitle);
var items = list.getItems(createQuery());
ctx.load(items);
ctx.executeQueryAsync(
function() {
complete(items.get_count());
},
function() {
complete(-1);
}
);
function createQuery()
{
var query = new SP.CamlQuery();
query.set_viewXml('<View Scope="RecursiveAll"><Query><Where><Eq><FieldRef Name="FSObjType" /><Value Type="Integer">0</Value></Eq></Where></Query></View>');
return query;
}
}
Usage
getItemsCount('Documents', function(itemsCount){
console.log(String.format('Total files count in Documents library: {0}',itemsCount));
});
I am working on an app to store data offline. My problem is when I try to retrieve the data from local storage for update/edit, it keeps calling only the id of the first item, and not calling the id of the data in view.
Please what am I doing wrong?
Here is my code for loading employees:
// load cases from localStorage
var employees;
if (localStorage.getItem('employees')) {
employees = JSON.parse(localStorage.getItem('employees'));
} else {
// If no cases, create and save them
employees = [];
// offling storing of our cases
localStorage.setItem('employees', JSON.stringify(employees));
}
// show case listing in list view page
var showEmployees = function () {
//erase existing content
$('#employee_list').html('');
//insert each employee
for (var i = 0; i<employees.length; i++) {
addEmployees(employees[i]);
}
};
Here is my code to add an employee to list view:
//add an eliment to list view
var addEmployees = function (empData) {
//HTML content of one list element
var listElementHTML = '<li><a class="employee_list" ui-btn ui-btn-e ui-btn-icon-right ui-icon-carat-r" data-transition="fade" data-split-icon="delete" href="#item'+empData.id+'">' + empData.employeename + '<br> ' + empData.dateofbirth + '</br></a></li>';
//appending the HTML code to list view
$('#employee_list').append(listElementHTML);
};
Here is my code for Edit function:
//User input to edit form
$('#edit_employee_page').on('click' , function () {
var editEmployee = JSON.stringify({
id: employees.length+1,
employeeno: $('#employeeno').val(),
employeename:$('#employeename').val(),
stateoforigine:$('#stateoforigine').val(),
employeephone: $('#employeephone').val(),
dateofbirth:$('#dateofbirth').val()
});
//Alter the slected data
localStorage.setItem("employees", JSON.stringify(employees));
return true;
});
for (var i in employees) {
var id = JSON.parse(localStorage.getItem(employees[i]));
}
Here is my code for the Edit button:
//register Edit button
$('.edit_button').live('click', function (e) {
alert('I was Cliked!');
e.stopPropagation();
$.each(employees, function(a, b) {
//if(b.id == employees[i]){
$('#id').val(b.id);
$('#employeeno').val(b.employeeno);
$('#employeename').val(b.employeename);
$("#stateoforigine").val(i.stateoforigine);
$('#employeephone').val(b.employeephone);
$('#dateofbirth').val(b.dateofbirth);
$("#id").attr("readonly","readonly");
$('#employeeno').focus();
$.mobile.changePage('#edit_employee_page');
return false;
//}
});
});
Here is my local Storage:
[
{"id":1,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1965"},
{"id":2,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1966"},
{"id":3,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1966"},
{"id":4,
"employeeno":"DAST/003/2003",
"employeename":"Gold Base",
"stateoforigine":"",
"employeephone":"",
"dateofbirth":"12/03/1986"}
]
Thanks for helping me out
The way you are storing your employees into localStorage is correct, but the way you are getting them out is incorrect. You stored your employees by stating:
localStorage.setItem("employees", JSON.stringify(employees));
So, in order to retrieve them, you must use:
var employees = JSON.parse(localStorage.getItem("employees"));
You see, you stored the data as a string with a key of "employees"; therefore, you can only retrieve it by that key. Since all data stored in localStorage is saved as a string, you must use JSON.parse() to convert the data back into an object - an array in this case. Then you can iterate over your employees.
Update:
You should be running this code as soon as the page is rendered (see below). I'm not sure how you're doing that - if you're using an IIFE or jQuery's document.ready() function. I don't think it's necessary to store an empty array into localStorage if none were loaded initially, so, I took your else clause out.
var employees = [];
if (localStorage.getItem('employees') !== null) {
employees = JSON.parse(localStorage.getItem('employees'));
}
Debug this line-by-line when it runs and make positive your employees variable contains data. If it doesn't contain data, well then, there's nothing to edit.
If, however, there is data, then execute your showEmployees() function. Oddly, I'm not seeing in your code where you actually call this. Is it bound to a button or action in your UI? Also, what is that for loop doing after your $('#edit_employee_page') click event function? It's trying to read data from localStorage improperly and it does nothing.
I think if you simply stepped through your code one line at a time using breakpoints and desk-checking your inputs/outputs you'd find out where you're going wrong.
It also appears that there's a disconnect in your code. May be you left out some lines; you define a string editEmployee but out of the blues you store JSON.stringify(employees) whereas employees is not defined in your code:
$('#edit_employee_page').on('click' , function(){
var editEmployee = JSON.stringify({
id: employees.length+1,
//........
});
//Alter the slected data
localStorage.setItem("employees", JSON.stringify(employees));
return true;
});
I had a similar task to do . I did it this way.
I passed the dynamic Id to be passed as an id attribute
id="'+empData.id+'"
and then inside the
$('.edit_button').live('click', function (e) {
alert('I was Cliked!');
var empId=$(this).attr('id');
rest of the code is same.
I am finding that in order to pass a variable to my database table I am having to create the variable as a global, which I would prefer not to do. However, I can't seem to figure out how to get the variable passed without using an anonymous function instead of "updateSelectedBird."
updateBirds(3); //this is normally called from within another function
function updateBirds(_birdIndex) {
var db = window.openDatabase("birdingDB", "1.0", "Birding DB", 200000);
birdIndex = _birdIndex;
db.transaction(updateSelectedBird, errorSelBirds);
}
function updateSelectedBird(tx) {
tx.executeSql('UPDATE Birds SET sighted = "1" WHERE id = ' + birdIndex);
}
function errorSelBirds(err) { /*error function*/ }
Any help would be appreciated.
Hey there I was having the same issue, but I found a work-around you have to use annoynmous self-calling functions. Annoying =/
db_callback = function(tx) {
for(var x in data) {
(function()
var _tmpX = x;
tx.executeSql("select from bla bla bla", [], function(tx2, result) {
console.log(_tmpX); //atleast this time it increments and isn't the last key of the data collection.
});
})();
}
}
I had this issue, because I wanted to check if data existed in the table already, while peforming a sync from the server. (I needed to check if rowID was in there already or not, since you can create things from the phone to!) - it became a tricky situation. And now I'm worried about memory consumption =/
Hope this helps you out however