I've asked similar questions a few different ways, but here's the simplest version of it - I am trying to increment through a list of keyname values when a function occurs. However, when the function is called, all I am getting is the text of the function itself. Here's a snippet -
var knlist = {
kn10:"2L1qvq6Tg6rMhEwNshr6dQ",
kn11:"2N_Cl_Gl5fX8_TdLgHP3rQ",
kn12:"2RbpjbhM3_EfzejfPgzwAw",
kn13:"2rP8y_ub_alGrzAK_aZrEg",
kn14:"2S8O9KBwxRlvtZX6kjyS0y",
kn15:"2Ua5EnPVDwd7LGq6UbT2bQ",
kn16:"3_17fNbyu2Yw8ozPx8BmkA",
kn17:"3LB0GSXXVadBlCMhSth3IA",
kn18:"48JvNwKSgvnWT8nqzWtE3Q",
kn19:"4CP5JE_mlMMzjvDMMgXncg",
}
var count = 11
var knx = function knxer(){
if (count === 11) {
knx = "kn11";
} else {
knx = ("kn" + count);
}};
var keyname = (knlist[knx]);
console.log (count)
console.log (knx)
console.log (keyname)
Console.log KNX is only giving me the text of the function knxer() itself rather than the expected values the function should return as the count increases.
Once this is solved, I'm going to be having another function increase the count within a different location - here's a full JSFiddle of where that is at. Once thats done I'm going to add an input for the login page so that username has a value that can be imputed the first time someone attempts the survey, and posts each completion over and over.
The problem is that you assign knix to your function
var knlist = {
kn10:"2L1qvq6Tg6rMhEwNshr6dQ",
kn11:"2N_Cl_Gl5fX8_TdLgHP3rQ",
kn12:"2RbpjbhM3_EfzejfPgzwAw",
kn13:"2rP8y_ub_alGrzAK_aZrEg",
kn14:"2S8O9KBwxRlvtZX6kjyS0y",
kn15:"2Ua5EnPVDwd7LGq6UbT2bQ",
kn16:"3_17fNbyu2Yw8ozPx8BmkA",
kn17:"3LB0GSXXVadBlCMhSth3IA",
kn18:"48JvNwKSgvnWT8nqzWtE3Q",
kn19:"4CP5JE_mlMMzjvDMMgXncg",
}
var count = 11
var knx;
function knxer(){
if (count === 11) {
knx = "kn11";
} else {
knx = ("kn" + count++); // update the count each time it calls
}};
knxer(); // call it
var keyname = (knlist[knx]);
console.log (count)
console.log (knx)
console.log (keyname)
you have to call the function ,
you are just mentioning function name in console.log() ,
This will call the function and will return the value console.log(knx())
This will NOT call the function instead,It will return the function body console.log(knx)
Related
I'm trying to make an app that will help me with my workouts and help me constantly lift more so that I can get stronger. I keep getting the error "Cannot set inner property of null" on the very bottom when I try to output the variables to the HTML. It's the code under the last section of comments that I am getting the error. Can some give me some guidance on how to fix this?
//Get the variables from the user. This will be the previous exercise or the exercise that the user has performed
const userSet = document.getElementById("set-user-1");
const userReps = document.getElementById("reps-user-1");
const userWeight = document.getElementById("weight-user-1");
var futureSet;
var futureReps;
var futureWeight;
//Define the functions that need to be done between the previous exercise and the next exercise
function getNewSet(previousSet) {
return previousSet;
}
function getNewRep(previousReps){
if(previousReps < 12) {
return previousReps + 2;
} else {
previousReps = 6;
return previousReps;
}
}
function getNewWeight(previousReps, previousWeight) {
if(previousReps < 12){
return previousWeight;
} else {
previousWeight = previousWeight + 10;
return previousWeight;
}
}
//Make a function that runs all the functions with the user input
function getNewWorkout() {
futureSet = getNewSet(parseInt(userSet));
futureReps = getNewRep(parseInt(userReps));
futureWeight = getNewWeight(parseInt(userReps, userWeight));
return futureSet;
return futureReps;
return futureWeight;
}
//Output will go to the future exercise dividers
document.getElementById("future-sets").innerHTML = futureSet;
document.getElementById("future-reps").innerHTML = futureReps;
document.getElementById("future-weight").innerHTML = futureWeight;
The error is in the last two lines of this function. A function can only return one value, it might be worth putting all the values in an array
and then returning it.
//Make a function that runs all the functions with the user input
function getNewWorkout() {
futureSet = getNewSet(parseInt(userSet));
futureReps = getNewRep(parseInt(userReps));
futureWeight = getNewWeight(parseInt(userReps, userWeight));
return futureSet;
//error here
return futureReps;
return futureWeight;
}
So you can update your code as follows to return object,
function getNewWorkout() {
const futureSet = getNewSet(parseInt(userSet));
const futureReps = getNewRep(parseInt(userReps));
const futureWeight = getNewWeight(parseInt(userReps, userWeight));
return {futureSet, futureReps, futureWeight};
}
Which you can access through object.
This kind of error comes when you load the script before DOM is ready. You can try to load the script at the end of the HTML, usually in footer. This should fix your error.
Also, please call the function 'getNewWorkout()' in your script to get expected output.
I am trying to update some data into my Firebase realtime database, but for some reason the code runs multiple times when i present it with a new string, this messes up the output of the code.
Below is what I have tried, I tried to create a new function for the ref.update(), but the same thing happens again, I have pointed in the comments of the code where exactly the code goes back to.
function fire_base_db() {
var ref = firebase.database().ref();
ref.on("value", function(snapshot) {
r = snapshot.val();
var ham_db = r.hams.spam_words;
var spam_db = r.spams.spam_words; //contains spam data now
console.log('function 1')
inputstring(ham_db, spam_db);
}, function(error) {
console.log("Error: " + error.code);
});
}
inputstring(ham_db, spam_db); //just a random function i need
spam_prop(user_string_toknized, spam_db, ham_db); //yet another
function spam_or_ham()
function spam_or_ham() {
var final_value = " ";
if (total_spam_probablity < total_ham_probablity) {
console.log("ham");
final_value = "ham";
} else {
console.log("spam");
final_value = "spam";
}
if (final_value = "spam") {
var ref = firebase.database().ref("hams/spam_words/");
ref.update(old_words_spam_2);
} else if (final_value = "ham") {
var ref2 = firebase.database().ref("spams/spam_words/")
ref2.update(old_words_ham_2)
};
for (var a in new_words_spam) {
new_words_spam[b] = 1
}
for (var b in new_words_ham) {
new_words_ham[a] = 1;
}
if (final_value = "spam") {
var ref9 = firebase.database().ref("spams/spam_words/")
ref9.update(new_words_spam)
} else if (final_value = "ham") {
var ref2 = firebase.database().ref("hams/spam_words")
ref2.update(new_words_ham)
}
}
fire_base_db_upadt_new_words();
fire_base_db_upadt_new_words_2();
The first function fire_base_db() is used to read data from the database, the next 2 functions are just some steps for the output, the last function spam_or_ham is where the bug appears, moment the code enters the if statement and reaches the ref9.update part, it runs back to ref.on in the first function and run multiple times, each time executing till the ref9 part, except in the last execution where the whole code is executed, I want the full code to be executed in the first time itself.
I am trying to compare a value with a list of value in for loop and show a single error message.
e.g.
I have 5 rows with 5 amount as a and one single amount value to compare
if one case fails its false only not true
var principalrowLen = $(".principalrow").length;
for(i=0;i<principalrowLen;i++){
var amountfiled = "amtTottal"+i;
var amountvalu = $("#"+amountfiled).val().substring(1, $("#"+amountfiled).val().length);
amtfinal =
}
if(amountvalu > toamt){
var amountCompMsg ="error msg";
$('#alert-warning-title').html("error msg");
$('#alert-warning-body').html(amountCompMsg);
$('#alert-warning').modal('show');
$('#alert-warning').on('hidden.bs.modal', function () {
$("html").removeClass("modalOpen");
})
$('#alert-warning').on('shown.bs.modal', function () {
$("html").addClass("modalOpen");
})
}
What you are missing is the "break" loop. You may need to compare each value with the "toamt" variable and if the "amountvalue" is greater than the value, you need to show the error message FIRST and then, break the loop.
let toamt = 0; // whatever you intend, I don't know where you get it.
var principalrowLen = $(".principalrow").length;
for(i=0;i<principalrowLen;i++){
var amountfiled = "amtTottal"+i;
var amountvalue = $("#"+amountfiled).val().substring(1, $("#"+amountfiled).val().length);
if(amountvalu > toamt){
var amountCompMsg ="error msg";
$('#alert-warning-title').html("error msg");
$('#alert-warning-body').html(amountCompMsg);
$('#alert-warning').modal('show');
$('#alert-warning').on('hidden.bs.modal', function () {
$("html").removeClass("modalOpen");
})
$('#alert-warning').on('shown.bs.modal', function () {
$("html").addClass("modalOpen");
});
break; // the "break" command stops the loop.
}
}
I really try my damndest not to ask, but i have to at this point before I tear my hair out.
By the time the js interpreter gets to this particular method, I can print it to the console no problem, it is an array of "event" objects. From FireBug I can see it, but when I try to set a loop to do anything with this array its as if it doesn't exist. I am absolutely baffled......
A few things:
I am a newbie, I have tried a for(var index in list) loop, to no avail, I have also tried a regular old for(var i = 0; i < listIn.length; i++), and I also tried to get the size of the local variable by setting var size = listIn.length.
As soon as I try to loop through it I get nothing, but I can access all the objects inside it from the FireBug console no problem. Please help, even just giving me a little hint on where I should be looking would be great.
As for the array itself, I have no problems with getting an array back from PHP in the form of: [{"Event_Id":"9", "Title":"none"}, etc etc ]
Here is my code from my main launcher JavaScript file. I will also post a sample of the JSON data that is returned. I fear that I may be overextending myself by creating a massive object in the first place called content, which is meant to hold properties such as DOM strings, settings, and common methods, but so far everything else is working.
The init() function is called when the body onload is called on the corresponding html page, and during the call to setAllEvents and setEventNavigation I am lost.
And just to add, I am trying to learn JavaScript fundamentals before I ever touch jQuery.
Thanks
var dom, S, M, currentArray, buttonArray, typesArray, topicsArray;
content = {
domElements: {},
settings: {
allContent: {},
urlList: {
allURL: "../PHP/getEventsListView.php",
typesURL: "../PHP/getTypes.php",
topicsURL: "../PHP/getTopics.php"
},
eventObjArray: [],
buttonObjArray: [],
eventTypesArray: [],
eventTopicsArray: []
},
methods: {
allCallBack: function (j) {
S.allContent = JSON.parse(j);
var list = S.allContent;
for (var index in list) {
var event = new Event(list[index]);
S.eventObjArray.push(event);
}
},
topicsCallBack: function(j) {
S.eventTopicsArray = j;
var list = JSON.parse(S.eventTopicsArray);
topicsArray = list;
M.populateTopicsDropDown(list);
},
typesCallBack: function(j) {
S.eventTypesArray = j;
var list = JSON.parse(S.eventTypesArray);
typesArray = list;
M.populateTypesDropDown(list);
},
ajax: function (url, callback) {
getAjax(url, callback);
},
testList: function (listIn) {
// test method
},
setAllEvents: function (listIn) {
// HERE IS THE PROBLEM WITH THIS ARRAY
console.log("shall we?");
for(var index in listIn) {
console.log(listIn[index]);
}
},
getAllEvents: function () {
return currentArray;
},
setAllButtons: function (listIn) {
buttonArray = listIn;
},
getAllButtons: function () {
return buttonArray;
},
setEventNavigation: function(current) {
// SAME ISSUE AS ABOVE
var l = current.length;
//console.log("length " + l);
var counter = 0;
var endIndex = l - 1;
if (current.length < 4) {
switch (l) {
case 2:
var first = current[0];
var second = current[1];
first.setNextEvent(second);
second.setPreviousEvent(first);
break;
case 3:
var first = current[0];
var second = current[1];
var third = current[2];
first.setNextEvent(second);
second.setPreviousEvent(first);
second.setNextEvent(third);
third.setPreviousEvent(second);
break;
default:
break;
}
} else {
// do something
}
},
populateTopicsDropDown: function(listTopics) {
//console.log("inside topics drop");
//console.log(listTopics);
var topicsDropDown = document.getElementById("eventTopicListBox");
for(var index in listTopics) {
var op = document.createElement("option");
op.setAttribute("id", "dd" + index);
op.innerHTML = listTopics[index].Main_Topic;
topicsDropDown.appendChild(op);
}
},
populateTypesDropDown: function(listTypes) {
//console.log("inside types drodown");
//console.log(listTypes);
var typesDropDown = document.getElementById("eventTypeListBox");
for(var index2 in listTypes) {
var op2 = document.createElement("option");
op2.setAttribute("id", "dd2" + index2);
op2.innerHTML = listTypes[index2].Main_Type;
typesDropDown.appendChild(op2);
}
}
},
init: function() {
dom = this.domElements;
S = this.settings;
M = this.methods;
currentArray = S.eventObjArray;
buttonArray = S.buttonObjArray;
topicsArray = S.eventTopicsArray;
typesArray = S.eventTypesArray;
M.ajax(S.urlList.allURL, M.allCallBack);
//var tempList = currentArray;
//console.log("temp array length: " + tempList.length);
M.setAllEvents(currentArray);
M.testList(currentArray);
M.setEventNavigation(currentArray);
//M.setEventNavigation();
M.ajax(S.urlList.topicsURL, M.topicsCallBack);
M.ajax(S.urlList.typesURL, M.typesCallBack);
}
};
The problem you have is that currentArray gets its value asynchronously, which means you are calling setAllEvents too soon. At that moment the allCallBack function has not yet been executed. That happens only after the current running code has completed (until call stack becomes emtpy), and the ajax request triggers the callback.
So you should call setAllEvents and any other code that depends on currentArray only when the Ajax call has completed.
NB: The reason that it works in the console is that by the time you request the value from the console, the ajax call has already returned the response.
Without having looked at the rest of your code, and any other problems that it might have, this solves the issue you have:
init: function() {
dom = this.domElements;
S = this.settings;
M = this.methods;
currentArray = S.eventObjArray;
buttonArray = S.buttonObjArray;
topicsArray = S.eventTopicsArray;
typesArray = S.eventTypesArray;
M.ajax(S.urlList.allURL, function (j) {
// Note that all the rest of the code is moved in this call back
// function, so that it only executes when the Ajax response is
// available:
M.allCallBack(j);
//var tempList = currentArray;
//console.log("temp array length: " + tempList.length);
M.setAllEvents(currentArray);
M.testList(currentArray);
M.setEventNavigation(currentArray);
//M.setEventNavigation();
// Note that you will need to take care with the following asynchronous
// calls as well: their effect is only available when the Ajax
// callback is triggered:
M.ajax(S.urlList.topicsURL, M.topicsCallBack); //
M.ajax(S.urlList.typesURL, M.typesCallBack);
});
}
Using the script below I'm attempting to create an object called temptagarray which gets populated with all the tags on a Tumblr weblog and their frequency. So it should end up looking like this:
{'performance': 10, 'installation': 5}
I know the object is being created and it looks correct (I can print it out in each loop) but I can't figure out how to use it after/outside the function i.e. at the bottom of the script where I attempt to document.write() it out. Is this a global/local variable issue, a return issue or do I need to address it in some way?
<script type="text/javascript">
var temptagarray = {};
var tags;
var tag;
function loadPosts () {
var key = "api_key=9I4rZAYQCbU1o5TSMZuyrlvXiQsNxKBicCJxNK5OKZ6G9pgdim";
var api = "https://api.tumblr.com/v2/blog/garrettlynch.tumblr.com/";
var retrieve_more = function (offset) {
$.getJSON(api + "posts?callback=?&filter=image&limit=20&offset=" + offset + "&" + key,function(data) {
//for each item (post) in the response
$.each(data.response.posts, function(i, item) {
//pull out the posts tags
tags = item['tags'];
//loop through the tags
for (i = 0; i < tags.length; i++)
{
tag = tags[i];
//if the tag already exists in the tag array
if (temptagarray[tag])
{
temptagarray[tag] = temptagarray[tag] + 1;
}
else
{
temptagarray[tag] = 1;
}
}
});
if (data.response.posts.length == 20) {
retrieve_more(offset + 20);
}
});
};
retrieve_more(0);
}
loadPosts();
document.write(JSON.stringify(temptagarray));
</script>
Thanks in advance
Garrett
Replace this:
if (data.response.posts.length == 20) {
retrieve_more(offset + 20);
}
...with this:
if (data.response.posts.length == 20) {
retrieve_more(offset + 20);
} else {
document.write(JSON.stringify(temptagarray));
}
The problem you're having is that, despite your document.write(...) command being located below the ajax call in your code, the ajax call is asynchronous and thus the callback will be invoked asynchronously as well. Basically, document.write(...) is being invoked long before you've had a chance to interact with the temptagarray variable in the ajax callback.
First things first - AJAX is Async Asynchronous.
So the code block does not wait for the previous instruction to be completed before it executes the next line.
So your document.writeline would have already been executed by the time the response comes back.
Try printing that info in the success call back after the if block and you would indeed see the response.
thanks for the replies. Below is what I have now as a workable solution as the result is going to call another function anyway. Reading a little bit more I'm wondering if I should be using a callback - is it better?
<script type="text/javascript">
//load posts from a Tumblr weblog
function loadPosts () {
//api key and weblog address
var key = "api_key=9I4rZAYQCbU1o5TSMZuyrlvXiQsNxKBicCJxNK5OKZ6G9pgdim";
var api = "https://api.tumblr.com/v2/blog/garrettlynch.tumblr.com/";
//tags object
var temptagarray = {};
//all tags and each tag
var tags;
var tag;
//looping function to keep retrieving posts until all are retrieved
var retrieve_more = function (offset) {
$.getJSON(api + "posts?callback=?&filter=image&limit=20&offset=" + offset + "&" + key,function(data) {
//for each item (post) in the response
$.each(data.response.posts, function(i, item) {
//pull out the posts tags
tags = item['tags'];
//loop through the tags
for (i = 0; i < tags.length; i++)
{
//pull out each tag
tag = tags[i];
//if the tag already exists in the tag array
if (temptagarray[tag])
{
//add 1 to its count
temptagarray[tag] = temptagarray[tag] + 1;
}
else
{
//set its count to 1
temptagarray[tag] = 1;
}
}
//to test object as it gets added to
//$("#Posts ul").append('<li>' + JSON.stringify(item, ['tags']) + '</li>')
});
//if the number of posts is more than 20
if (data.response.posts.length == 20)
{
//retrieve the next 20
retrieve_more(offset + 20);
}
else
{
//call the show result function
showresult(temptagarray);
}
});
};
//stop retrieving posts
retrieve_more(0);
}
loadPosts();
function showresult(tagarray)
{
$("#Posts ul").append('<li>' + JSON.stringify(tagarray) + '</li>');
//document.write(JSON.stringify(tagarray));
}
</script>