Javascript variable not updating its value - javascript

I set the following in my console:
document.getElementById('messsages').textContent;
which gave me the output "this is a message i sent through websocket chat!"
I then did
var convo = document.getElementById('messsages').textContent;
and typed in convo into the console and it gave me the same output as before. I then sent another message through my websocket chat and typed in convo and it gave me the old output but when I typed in document.getElementById('messsages').textContent; it gave me the new output.
Why is this? And is there a method for me to assign a variable which updates its value accordingly with my element?

Try utilizing an IIFE
var convo = function convo() {
return (function(elem) {
return elem.textContent
}(document.getElementById("messages"))
};
See also MutationObserver
setInterval(function() {
var arr = "abcdefg".split("");
var i = 1 + Math.floor(Math.random() * arr.length -1);
document.getElementById("messages").textContent = arr[i];
}, 2000);
var convo = function convo() {
return (function(elem) {
return elem.textContent
}(document.getElementById("messages")))
};
document.addEventListener("click", function() {
console.log(convo())
});
click
<div id="messages"></div>

Related

MongoDB Scheduled Trigger Save Error -- What to Return?

This problem is very annoying. So, I am making a scheduled trigger run every 24 hours. It simply gets items from one collection does some data processing then appends information to another collection. The functioning code works even when the function runs. But it will not let me save because there are "runtime" errors? Even though it was executed perfectly and returned.
Console Error
> result (JavaScript):
EJSON.parse('{"$undefined":true}')
I suppose this has something to do with returning. but when I return null I get this:
> result:
null
> result (JavaScript):
EJSON.parse('null')
when trying to save I get this at the top of the page:
runtime error during function validation
Function Code:
exports = async function() {
const usersCol = context.services.get("SchoologyDashCluster").db("SchoologyDashApp").collection("users");
const gradesCol = context.services.get("SchoologyDashCluster").db("SchoologyDashApp").collection("grades");
var usersCusor = await usersCol.find( ).toArray();
var gradesCusor = await gradesCol.find( ).toArray();
let insert = [];
for (let i = 0; i < usersCusor.length; i++) {
var user = usersCusor[i];
var userSavedGrades = gradesCusor[i].grades
var currentGrades = await getGrades(user.schoologyUID, user.consumerKey, user.secretKey);
var lastGraded = NaN;
let index = gradesCusor[i].grades.length - 1;
while (true) {
if (gradesCusor[i].grades[index].changed == 1) {
lastGraded = index;
break
}
index = index - 1;
}
console.log(lastGraded)
if (userSavedGrades[lastGraded].grades.ga == currentGrades.ga){
currentGrades = { changed : 0, time: new Date().getTime()};
} else {
currentGrades = {changed : 1, grades: currentGrades, time : new Date().getTime()};
}
gradesCol.updateOne(
{"user" : user._id},
{"$push" : {"grades" : currentGrades}}
)
}
// return usersCol.find( );
return null;
};
The answer was simple and now I feel ignorant. Instinctual I put the module imports at the top of the document. However this is incorrect and they need to be placed in the exports function, like so:
exports = function (x,y,z) {
const http = context.http;
return;
}

retrieverecord not assigning the value to the value from the web api?

I'm creating a var where I want to assign it to a var that I get from another entity
function SubmitAction(executionContext) {
var lookupItem = formContext.getAttribute("alfa_member").getValue()[0].id;
var theTotalMembersTravling = formContext.getAttribute("alfa_numberofdependent").getValue();
var remainFlightCredit;
debugger;
Xrm.WebApi.online.retrieveRecord("contact",lookupItem, "?$select=new_remainstravelcredit").then(
function employessPackage(result) {
var new_remainstravelcredit = result["new_remainstravelcredit"];
if(new_remainstravelcredit !== null){
if(new_remainstravelcredit > 0)
{
remainFlightCredit = new_remainstravelcredit;
console.log(remainFlightCredit+" This not inside any if condition");
var newRemain = (parseInt(remainFlightCredit)) - (parseInt(theTotalMembersTravling));
console.log(newRemain+ " This in the remain if condition");
var entity = {};
entity.new_remainstravelcredit = newRemain.toString();
Xrm.WebApi.online.updateRecord("contact",lookupItem, entity).then(
function success(result) {
var updatedEntityId = result.id;
},
function(error) {
Xrm.Utility.alertDialog(error.message);
}
);
} if(new_remainstravelcredit <= 0)
{
Xrm.Utility.alertDialog("You have exceeds the travel credit");
console.log(remainFlightCredit);
}
}
},
function(error) {
Xrm.Utility.alertDialog(error.message);
}
);
console.log(remainFlightCredit);
}
So as result in this line
remainFlightCredit = new_remainstravelcredit;
console.log(remainFlightCredit+" This not inside any if condition");
Which inside the webapi call I'm able to get the value but outside in the main function at the end when I write
console.log(remainFlightCredit);
I'm unable to get the value remainFlightCredit, do you have any suggestions to solve this issue?
This is expected behavior, as this is a promise call (asynchronous) the code outside the main api call will execute before the success callback function employessPackage.
So remainFlightCredit value get assigned after the last console.log line in your code.
You can place a breakpoint to debug and see it in action.

Call variable value in another .js file

I have 2 soy.js and lib-dialogs.js files.
I need to make lib-dialogs pass the value of the lineCount variable to soy.js.
I was able to do this with localStorage but because it saves in a cookie it does not update the values correctly.
In lib-dialogs there is a function called BlocklyDialogs.congratulations that calls the necessary data.
FIle:lib-dialogs.js
BlocklyDialogs.congratulations = function() {
// Add the user's code.
if (BlocklyGames.workspace) {
var linesText = document.getElementById('dialogLinesText');
linesText.textContent = '';
// Line produces warning when compiling Puzzle since there is no JavaScript
// generator. But this function is never called in Puzzle, so no matter.
var code = Blockly.JavaScript.workspaceToCode(BlocklyGames.workspace);
code = BlocklyInterface.stripCode(code);
var noComments = code.replace(/\/\/[^\n]*/g, ''); // Inline comments.
noComments = noComments.replace(/\/\*.*\*\//g, ''); /* Block comments. */
noComments = noComments.replace(/[ \t]+\n/g, '\n'); // Trailing spaces.
noComments = noComments.replace(/\n+/g, '\n'); // Blank lines.
noComments = noComments.trim();
var lineCount = noComments.split('\n').length;
var pre = document.getElementById('containerCode');
pre.textContent = code;
if (typeof prettyPrintOne == 'function') {
code = pre.innerHTML;
code = prettyPrintOne(code, 'js');
pre.innerHTML = code;
}
if (lineCount == 1) {
var text = BlocklyGames.getMsg('Games_linesOfCode1');
} else {
var text = BlocklyGames.getMsg('Games_linesOfCode2')
.replace('%1', String(lineCount));
}
linesText.appendChild(document.createTextNode(text));
}
FIle:soy.js
example "var count = BlocklyDialogs.congratulations(lineCount);"
In soy.js I need to receive the values of lineCount. I've already managed to do this using localStorage but I needed to do something more direct.
In testing I verified that the problem is in the lineCount variable because it is not passing a value to any variable even within the file itself.
I created a variable outside the blocklyDialogs.congratulations function and entered a value of 5.
I called the variable in the soy.js file and got it normally.
I need to make the lineCount pass its value.
You can use event driven programming, pub-sub model.
class EventManager {
constructor(...listeners) {
this.listeners = listeners;
}
register(fn) {
const id = this.listeners.push(fn);
return () => {
this.listeners.splice(id - 1, 1);
};
}
emit(data) {
this.listeners.forEach(fn => fn(data));
}
}
const pushEvents = new EventManager();
// JS 1
const unsubscribe1 = pushEvents.register(x => {
console.log("event:", x);
});
pushEvents.register(x => {
console.log("event:", x);
});
// JS 2
pushEvents.emit("Tets data");
//Output
// event: Tets data
// event: Tets data
unsubscribe1();
pushEvents.emit("Tets data2");
//Output
// event: Tets data2
.as-console-row {color: red!important}

Simpy cannot iterate over javascript object?

I have scoured the other question/answer for this and implemented everything and I still cannot access the values of the object. Here's the code I am using:
function apply_voucher(voucher) {
var dates = $.parseJSON($("[name='dates']").val());
var voucher_yes_no = new Array();
var voucher_reduction = new Array();
if(voucher.length > 0)
{
$.each(dates, function(room_id, these_dates) {
$.post('/multiroom/check_voucher/'+voucher+'/'+room_id, function(result) {
if(result.result == 'ok') {
voucher_yes_no.push('yes');
voucher_reduction.push(result.voucher_reduction);
} else {
voucher_yes_no.push('no');
}
}, 'json');
});
// check if there are any yes's in the array
if('yes' in voucher_yes_no) {
console.log("no yes's");
} else {
console.log(voucher_reduction);
console.log(typeof voucher_reduction);
for (var prop in voucher_reduction) {
console.log(prop);
console.log(voucher_reduction[prop]);
if (voucher_reduction.hasOwnProperty(prop)) {
console.log("prop: " + prop + " value: " + voucher_reduction[prop]);
}
}
}
}
}
Apologies for the constant console logging - I'm just trying to track everything to make sure it's all doing what it should. The console output I get from this is below:
...which shows the object containing one value, "1.01" and my console.log of the typeof it to make sure it is actually an object (as I thought I was going mad at one point). After this there is nothing from inside the for-in loop. I have tried jquery's $.each() also to no avail. I can't understand why nothing I'm trying is working!
It does not work because the Ajax call is asynchronous!
You are reading the values BEFORE it is populated!
Move the code in and watch it magically start working since it will run after you actually populate the Array!
function apply_voucher(voucher) {
var room_id = "169";
var dates = $.parseJSON($("[name='dates']").val());
var voucher_reduction = new Array();
$.post('/multiroom/check_voucher/'+voucher+'/'+room_id, function(result) {
if(result.result == 'ok') {
voucher_reduction.push(result.voucher_reduction);
}
console.log(voucher_reduction);
console.log(typeof voucher_reduction);
for (var prop in voucher_reduction) {
console.log(prop);
console.log(voucher_reduction[prop]);
if (voucher_reduction.hasOwnProperty(prop)) {
console.log("prop: " + prop + " value: " + voucher_reduction[prop]);
}
}
}, 'json');
}
From what it looks like, you plan on making that Ajax call in a loop. For this you need to wait for all of the requests to be done. You need to use when() and then(). It is answered in another question: https://stackoverflow.com/a/9865124/14104
Just to say for future viewers that changing the way I did this to use proper deferred objects and promises, which blew my head up for a while, but I got there! Thanks for all the help, particularly #epascarello for pointing me in the right direction :) As soon as I started doing it this way the arrays began behaving like arrays again as well, hooray!
Here's the final code:
function apply_voucher(voucher) {
var booking_id = $("[name='booking_id']").val();
var dates = $.parseJSON($("[name='dates']").val());
if(voucher.length > 0) {
var data = []; // the ids coming back from serviceA
var deferredA = blah(data, voucher, dates); // has to add the ids to data
deferredA.done(function() { // if blah successful...
var voucher_yes_no = data[0];
var voucher_reduction = data[1];
if(voucher_yes_no.indexOf("yes") !== -1)
{
console.log("at least one yes!");
// change value of voucher_reduction field
var reduction_total = 0;
for(var i = 0; i < voucher_reduction.length; i++) {
reduction_total += voucher_reduction[i];
}
console.log(reduction_total);
}
else
{
console.log("there are no yes's");
}
});
}
}
function blah(data, voucher, dates) {
var dfd = $.Deferred();
var voucher_yes_no = new Array();
var voucher_reduction = new Array();
var cycles = 0;
var dates_length = 0;
for(var prop in dates) {
++dates_length;
}
$.each(dates, function(room_id, these_dates) {
$.post('/multiroom/check_voucher/'+voucher+'/'+room_id, function(result) {
if(result.result == 'ok') {
voucher_reduction.push(result.voucher_reduction);
voucher_yes_no.push('yes');
} else {
voucher_yes_no.push('no');
}
++cycles;
if(cycles == dates_length) {
data.push(voucher_yes_no);
data.push(voucher_reduction);
dfd.resolve();
}
}, 'json');
});
return dfd.promise();
}
Can you show how voucher_reduction is defined?
I am wondering where the second line of the debug output comes from, the one starting with '0'.
in this line:
console.log(vouncher_reduction[prop]);
^
The name of the variable is wrong (then) and probably that is breaking your code.
I think there are no problem with your loop.
But perhaps with your object.
Are you sure what properties has enumerable ?
Try to execute this to check :
Object.getOwnPropertyDescriptor(voucher_reduction,'0');
If it return undefined, the property was not exist.

knockout push values array

when I click on button1 I get object with 50 contacts array (containing collection of arrays with phoneNumbers, Addresses...), then when I click on button 2 I get the same object but my first object is erased whereas I would like to display 50 + 50 = 100 contacts array. I tried concat method but I have some difficulties to implement.
viewModel.initializeListener = function() {
$('#button1').click(function() {
document.getElementById("button2").style.visibility = "hidden";
$('#retrievedContactsDiv').html('');
nbDisplayedContacts = 0;
console.info("test");
viewModel.ui.FlashbackReport.MoreContacts();
});
$('#button2').click(function() {
viewModel.ui.FlashbackReport.MoreContacts();
console.info("test");
});
}; `
viewModel.WeHaveMoreContacts = function(data) {
console.info("test:", data)
if (viewModel.MoreContacts) {
var newArray=ko.mapping.fromJS(data, viewModel.MoreContacts);
var concatenated = newArray.concat(dataArray);
viewModel.MoreContacts.contacts(concatenated);
} else {
viewModel.MoreContacts = ko.mapping.fromJS(data);
var dataArray = viewModel.MoreContacts.contacts();
}
I have a parameter with number of contacts to skip for the server.
function which call the server then call the mapping function :
viewModel.ui.FlashbackReport.MoreContacts()
Problem : Object # has no method 'concat'
I made a fiddle that may help you.
The first part of the function generates new contacts and the second one add them to the existing contacts.
var VM = function () {
var self = this;
self.contacts = ko.observableArray();
self.addMore = function () {
// simulate server response
var offset = self.contacts().length;
var dataFromServer = [];
for (var index = 0; index < 10; index++) {
dataFromServer.push({
name: 'contact ' + offset + index
});
}
// add each new item to existing items.
ko.utils.arrayForEach(dataFromServer, function (item) {
self.contacts.push(item);
});
};
}
Feel free to ask more explanation.
I hope it helps.

Categories