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.
Related
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)
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've written two functions as shown below. The bottom one is returning 'undefined' for 'startAndEndDates' for some reason even though the console log above the return in findStartEndDates() is telling me the two values are set. What am I missing?
export function findBillingCycle(day_of_reservation) {
let reservation_date = moment.utc(day_of_reservation).format();
let fifteenth = moment();
fifteenth = fifteenth.startOf('day');
fifteenth = moment.utc(fifteenth);
let fourteenth = moment();
fourteenth = fourteenth.endOf('day');
fourteenth = moment.utc(fourteenth);
fourteenth.date(14);
if (fifteenth.date() < 15) {
fifteenth.subtract(1, 'month');
} else {
fourteenth.add(1, 'month');
}
fifteenth.date(15);
let startAndEndDates = findStartEndDates(reservation_date, fifteenth, fourteenth);
console.log(startAndEndDates);
return startAndEndDates;
}
function findStartEndDates(reservation_date, fifteenth, fourteenth) {
if (moment(reservation_date).isBefore(fifteenth)) {
fifteenth = moment(fifteenth).subtract(1, 'month');
fourteenth = moment(fourteenth).subtract(1, 'month');
}
if (moment(reservation_date).isAfter(fourteenth)) {
fifteenth = moment(fifteenth).add(1, 'month');
fourteenth = moment(fourteenth).add(1, 'month');
}
if (!moment(reservation_date).isBefore(fifteenth) && !moment(reservation_date).isAfter(fourteenth)) {
console.log('returning 15th = ' + moment(fifteenth).format('YYYY-MM-DD'));
console.log('returning 14th = ' + moment(fourteenth).format('YYYY-MM-DD'));
return {
fifteenth: fifteenth,
fourteenth: fourteenth
};
} else {
findStartEndDates(reservation_date, fifteenth, fourteenth);
}
}
You can use the following as test data:
reservation_date: 2018-09-07T13:45:00Z
fifteenth: moment.utc("2018-06-15T05:00:00.000+00:00")
fourteenth: moment.utc("2018-07-14T04:59:59.999+00:00")
Update:
Found a workaround by creating the two other dates (fifteenth/fourteenth) in the same month that reservation_date takes place in. Then it's just a simple logic check to determine if I need to roll back or forward one month. I just do this all in one function so I don't need to rely on another function.
Your problem is most likely due to these lines in your findStartEndDates function:
} else {
findStartEndDates(reservation_date, fifteenth, fourteenth);
}
You're making a recursive call in the else case, but you don't return the result of this recursive call. This means that the function gets called as intended, the console.log()s work as expected, but the return value is never passed down through the call stack so you end up with undefined.
You need to change the aforementioned lines of code into this:
} else {
return findStartEndDates(reservation_date, fifteenth, fourteenth);
}
I think the issue is to due with the way you wrote your return, try the following:
var values = [fifteenth, fourteenth];
return values;
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.
}
}
basic JS question, please go easy on me I'm a newb :)
I pass 2 variables to the findRelatedRecords function which queries other related tables and assembles an Array of Objects, called data. Since findRelatedRecords has so many inner functions, I'm having a hard time getting the data Array out of the function.
As it currently is, I call showWin inside findRelatedRecords, but I'd like to change it so that I can get data Array directly out of findRelatedRecords, and not jump to showWin
function findRelatedRecords(features,evtObj){
//first relationship query to find related branches
var selFeat = features
var featObjId = selFeat[0].attributes.OBJECTID_1
var relatedBranch = new esri.tasks.RelationshipQuery();
relatedBranch.outFields = ["*"];
relatedBranch.relationshipId = 1; //fac -to- Branch
relatedBranch.objectIds = [featObjId];
facSel.queryRelatedFeatures(relatedBranch, function(relatedBranches) {
var branchFound = false;
if(relatedBranches.hasOwnProperty(featObjId) == true){
branchFound = true;
var branchSet = relatedBranches[featObjId]
var cmdBranch = dojo.map(branchSet.features, function(feature){
return feature.attributes;
})
}
//regardless of whether a branch is found or not, we have to run the cmdMain relationship query
//the parent is still fac, no advantage of the parent being branch since cmcMain query has to be run regardless
//fac - branch - cmdMain - cmdSub <--sometimes
//fac - cmdMain - cmdSub <-- sometimes
//second relationship query to find related cmdMains
var relatedQuery = new esri.tasks.RelationshipQuery();
relatedQuery.outFields = ["*"];
relatedQuery.relationshipId = 0; //fac -to- cmdMain
relatedQuery.objectIds = [featObjId];
//rather then listen for "OnSelectionComplete" we are using the queryRelatedFeatures callback function
facSel.queryRelatedFeatures(relatedQuery, function(relatedRecords) {
var data = []
//if any cmdMain records were found, relatedRecords object will have a property = to the OBJECTID of the clicked feature
//i.e. if cmdMain records are found, true will be returned; and continue with finding cmdSub records
if(relatedRecords.hasOwnProperty(featObjId) == true){
var fset = relatedRecords[featObjId]
var cmdMain = dojo.map(fset.features, function(feature) {
return feature.attributes;
})
//we need to fill an array with the objectids of the returned cmdMain records
//the length of this list == total number of mainCmd records returned for the clicked facility
objs = []
for (var k in cmdMain){
var o = cmdMain[k];
objs.push(o.OBJECTID)
}
//third relationship query to find records related to cmdMain (cmdSub)
var subQuery = new esri.tasks.RelationshipQuery();
subQuery.outFields = ["*"];
subQuery.relationshipId = 2;
subQuery.objectIds = [objs]
subTbl.queryRelatedFeatures(subQuery, function (subRecords){
//subRecords is an object where each property is the objectid of a cmdMain record
//if a cmdRecord objectid is present in subRecords property, cmdMain has sub records
//we no longer need these objectids, so we'll remove them and put the array into cmdsub
var cmdSub = []
for (id in subRecords){
dojo.forEach(subRecords[id].features, function(rec){
cmdSub.push(rec.attributes)
})
}
var j = cmdSub.length;
var p;
var sub_key;
var obj;
if (branchFound == true){
var p1 = "branch";
obj1 = {};
obj1[p1] = [cmdBranch[0].Branches]
data.push(obj1)
}
for (var i=0, iLen = cmdMain.length; i<iLen; i++) {
p = cmdMain[i].ASGMT_Name
obj = {};
obj[p] = [];
sub_key = cmdMain[i].sub_key;
for (var j=0, jLen=cmdSub.length; j<jLen; j++) {
if (cmdSub[j].sub_key == sub_key) {
obj[p].push(cmdSub[j].Long_Name);
}
}
data.push(obj);
}
showWin(data,evtObj) <---this would go away
})
}
//no returned cmdRecords; cmdData not available
else{
p = "No Data Available"
obj = {}
obj[p] = []
data.push(obj)
}
showWin(data,evtObj) <--this would go away
})
})
}
I'd like to have access to data array simply by calling
function findRelatedRecords(feature,evt){
//code pasted above
}
function newfunct(){
var newData = findRelatedRecords(feature,evt)
console.log(newData)
}
is this possible?
thanks!
Edit
Little more explanation.....
I'm connecting an Object event Listener to a Function like so:
function b (input){
dojo.connect(obj, "onQueryRelatedFeaturesComplete", getData);
obj.queryRelatedFeatures(input);
console.log(arr) //<----this doesn't work
}
function getData(relatedFeatData){
var arr = [];
//populate arr
return arr;
}
So when obj.QueryRelatedFeatures() is complete, getData fires; this part works fine, but how to I access arr from function b ?
Post Edit Update:
Due to the way that this event is being hooked up you can't simple return data from it. Returning will just let Dojo call to the next method that is hooked up to onSelectionComplete.
When init runs it is long before findRelatedRecords will ever be executed/fired by the onSelectionComplete event of the well, which is why you were seeing undefined/null values. The only way to work with this sort of system is to either 1) call off to a method like you're already doing or 2) fire off a custom event/message (technically it's still just calling off to a method).
If you want to make this method easier to work with you should refactor/extract snippets of it to make it a smaller function but contained in many functions. Also, changing it to have only one exit point at the end of the findRelatedRecords method will help. The function defined inside of subTbl.queryRelatedFeatures() would be a great place to start.
Sorry, you're kind of limited by what Dojo gives you in this case.
Pre Edit Answer:
Just return your data out of it. Everywhere where there is a showWin call just use this return.
return {
data: data,
evtObj: evtObj
}
Then your newfunct would look like this.
function newfunct(){
var newData = findRelatedRecords(feature,evt);
console.log(newData);
console.log(newData.data);
console.log(newData.evtObj);
}
If you only need that "data" object, then change your return to just return data;.
Also, start using semicolons to terminate statements.