When I console.log a value, I get immediate response. But, the html takes time.
I know what the issue is and it has nothing to do with async or anything.
Is there a way to get what you are console.logging without doing a return?
Possibly saving it in localStorage.
"status" comes from third party API where it's boolean.The value changes from true to false based on user input. Which is correct. But, HTML takes time for it to change in timely manner
public elementEvent($event) {
this.isValid = $event.status;
console.log($event.status);
}
//output: true
<div>{{isValid}}</div>
//output: false
So here is what I had to do:
public elementEvent($event) {
this.isValid = $event.status;
this.ref.detectChanges();
}
Related
What I am trying to do is to switch out an object's property (a string) with a matching (keyed) object from another object where the values are keyed.
So for example...
const dataRefs = {
'idkey1': { title: "Key1", /*...etc... */ },
'idkey2': { title: "Key2", /*...etc... */ },
'idkey3': { title: "Key3", /*...etc... */ },
// ...etc...
};
const pages = [
{ title: "A Page", data: 'idkey1' },
// ...etc...
];
Using the below code I want to switch out pages[n].data with the matching property in dataRefs. So using a forEach on the pages...
pages.forEach(page => page.data = dataRefs[page.data])
Doing this results in page.data property becoming undefined, even though it should match.
If I try to debug by outputting it to console, I get some unusual effect of seeing the undefined only when the code is added after the output....
// This works and does the match exactly as I want it.
pages.forEach(page => console.log("%s: ", page.data, dataRefs[page.data]));
// Output:
// idkey1: undefined
// This however results in bizzare behaviour and ends up with "undefined".
pages.forEach(page => {
// using console.log to see what's going on...
console.log("%s: ", page.data, dataRefs[page.data]);
page.data = dataRefs[page.data];
});
// Output:
// [Object object]: undefined
// Trying this alternative, just in case how the DOM inspector
// might be using references, but still the same issue...
pages.forEach(page => {
console.log(page.data + ": ", dataRefs[page.data]);
page.data = dataRefs[page.data];
});
// Output:
// [Object object]: undefined
Have checked spelling of variables and gone over and over the code trying so many variants but it seems that no matter what I do, calling page.data = dataRefs[page.data] does not work. Would this be some sort of complex race-condition or have I been watching too much Matrix of late?
This is being called in the Component's render() method.
Using Safari 14.1.2, if that helps.
The issue was related with Next.JS. Best guess is that Next.JS was pre-rendering the data, storing it in some JSON cache file and passing that to the component render function....or something like that.
Using the browser's inspector, a breakpoint at the problematic line page.data = dataRefs[page.data] was only ever triggered once, and showed the data had already been manipulated by the function, before it had been called. Which is simply odd. Removing the line, the breakpoint would trigger and the data not converted.
This leads me to believe it to be some sort of NextJS pre-lifecycle thing, possibly as part of the SSG process.
To resolve the issue and move on, I used a check if (page.data instanceof Object) return; to stop it from running twice, which seemed to do the trick. Not ideal, but without a better reason, this will have to suffice. So the code ultimately went like....
pages.forEach(page => {
// skip the loop if the data has already been converted
// could have also used a string check, but both should work for now.
if (page.data instanceof Object) return;
// now change the data if it's still a string referrence
page.data = dataRefs[page.data]));
});
Again, appologies that I don't have the best answer, but this was the only way to resolve it, and since Javascript does not do this normally (have done this sort of thing so many times without issue), it will have to be chalked up to a NextJS/SSG (or some other processor) issue.
Would love to get any NextJS expert's knowledge on how this could happen.
This is my first post and I am thankful in advance for all the support.
Short background:
I am part of a script team developing a script to make our tasks easier. We are using a MySQL DB to allow the team choose which features we create each wants to use. The DB is working fine, as well as the data retrieval.
Issue:
Even though the cookies we create are set to hold the boolean value False, a function is always executing the if clause it holds.
function tkAlwaysViewAll(snippet) {
console.log('Viewall: ' + snippet);
if (snippet) {
var ticketURL = window.location.href;
var showAllURL, x;
x = ticketURL.indexOf('block=');
// if the string 'block=' does not exist in the URL, it adds the parameter and
// reloads the ticket to the correct 'view all' URL
if (x == -1) {
showAllURL = ticketURL + '&block=15:.a';
window.location.href = showAllURL;
} else {
console.log('Viewall function executed');
}
}
}
The code above should execute only when the value of snippet is set to True. However, it is being executed always, ignoring the value of snippet. Below you see the output of the console.log() which has been included for the debugging only.
The first console.log() displays the value of the snippet variable.
The second console.log() will be displayed only after the page has been reloaded (or when directly using the link with the 'block' parameter, but we are aware of this and not using it).
When snippet is True:
Viewall: true
Viewall function executed
And when the snippet is False (function should not be executed):
Viewall: false
Viewall function executed
The function is not using any global variables nor being altered by any other events.
What am I doing wrong in this function?
Best regards
The reason is that you pass a String "false" to your function (cookies always store Strings). Putting that in an if() condition internally converts that String to a Boolean value. Non-empty strings are converted to true in that mechanism.
Here's what Javascript does with non-Boolean values when converting:
// converts val to Boolean and returns it
function truthy(val) {
return Boolean(val)
}
console.log(truthy("true")) // true
console.log(truthy("false")) // true
console.log(truthy("")) // false
console.log(truthy(1)) // true
console.log(truthy(0)) // false
console.log(truthy([])) // true
console.log(truthy([].length)) // false
console.log(truthy({})) // true
Could you please help with something?
I’m trying to do the following…
import {chosenIpAddress} from './socketEvents.js';
const socket = socketClient(`http:// ${chosenIpAddress} :8081`);
…but no matter what I try, it simply ignores my expression and sees it as http://:8081. I’ve tried with plus signs, commas, backticks, quotation marks, shouting, and threatening it, but to no avail.
I can log out the IP address, so I know it’s populated, but as part of the string it just gets ignored and it’s driving me crazy!
Thanks in advance xxx
P.S... I've seen some similar questions, but these do not help with mine, hence the new question.
Update: As requested, this is my export...
let chosenIpAddress = "";
function chosenTank(tank) {
socket.emit('chosen tank', tank);
console.log('Tank', tank);
chosenIpAddress = tank.IpAddress;
}
export {
chosenIpAddress,
};
You need to export a function that returns the IP address when called.
The file importing the chosenIpAddress has the original value (empty string), but it will never be updated even when chosenTake is called. Javascript strings are copied by value, so if you update the original variable, any other references to it will not be updated.
https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
Example of strings copied by value:
chosenIpAddress = "";
x = chosenIpAddress; // x is ""
chosenIpAddress = "localhost"; // chosenIpAddress is "localhost", x is still ""
// This same issues applies to imports/exports.
So do something like this in your ip address file:
let chosenIpAddress = "";
function chosenTank(tank) {
socket.emit('chosen tank', tank);
console.log('Tank', tank);
chosenIpAddress = tank.IpAddress;
}
function getChosenIpAddress() {
// This can be "" if chosenTank is not called first
return chosenIpAddress;
}
export {
getChosenIpAddress,
};
Also, as pointed out in the comments, you need to call chosenTank before you access the chosenIpAddress, or you're going to get an empty string every time.
Further, you'll also need to build the socket string as a function as well, so that it gets the most up-to-date value from getChosenIpAddress when it's called:
import {getChosenIpAddress} from './socketEvents.js';
function getChosenSocket() {
return socketClient(`http://${getChosenIpAddress()}:8081`);
}
So, for anyone who runs into this problem, I worked it out. The answer given is kind of getting there, but not right, I tried that (and variations of it), but it/they didn't work.
Basically in my case, the IP address was being set when the application started, so the chosenIpAddress would always be an empty string as it's being set before the connections had taken place, no variations of exporting, recalling, or function building would've done the job.
To get around this, I let the initial connection take place with a 'placeholder' socketClient to stop the application from crashing...
let socket = socketClient('http://:8081');
...and then when ready, I called to repopulate the IP address when the component mounted from the frontend...
Called from front end when ready...
componentDidMount() {
frontEndConnected();
}
Add IP address as required...
function frontEndConnected() {
socket = socketClient(`http://${chosenTankIpAddress}:8081`);
}
...which works a charm.
So, I've got a notepad extension for Google Chrome that syncs and displays stored notes from a user. Currently my problem is as follows.
When the extension is run for the first time after download, the word 'undefined' is displayed in the editable div (id = edit_notepad). I want it to just be blank instead of displaying anything. Obviously, I know its undefined because the user hasn't been able to add any text yet.
Picture of what's displayed on initial run:
From my content script, here are my chrome.storage get and set functions (which do work):
document.body.onload = function() {
chrome.storage.sync.get("edit_notepad", function(items) {
if (!chrome.runtime.error) {
console.log(items);
document.getElementById("edit_notepad").innerHTML = items.edit_notepad;
}
});
}
document.getElementById("edit_notepad").onkeyup = function() {
var d = document.getElementById("edit_notepad").innerHTML;
chrome.storage.sync.set({ "edit_notepad" : d }, function() {
if (chrome.runtime.error) {
console.log("Runtime error.");
}
});
}
I presume I'm going to need some sort of if statement, but after hours of playing around, I'm lost as to what exactly it'd contain. The issue I've kept running into is that whatever I set the initial value of edit_notepad to, it always reverts back to "undefined" even when a user has written some notes! e.g. "This is a notes test" would revert back to "undefined" when the notepad is closed and reopened.
Well, an easy way to do this would be to specify a default value in your chrome.storage.sync.get(). Doing so would apply the default value when the key does not exist in the storage. However, given that you are replacing any contents which might already exist, the better solution would be not to set the contents when you have no value, or an invalid value, stored. The only valid value will be a string. This will prevent you from overwriting any default value supplied by the webpage when you have no value stored. Thus, an if statement something like the following should work (alternately, you could test for !== 'undefined':
document.body.onload = function() {
chrome.storage.sync.get("edit_notepad", function(items) {
if (!chrome.runtime.error) {
console.log(items);
if(typeof items.edit_notepad === 'string') {
document.getElementById("edit_notepad").innerHTML = items.edit_notepad;
}
}
});
}
Note: Storing the contents of the editable <div> on every key will result in many users running into both the MAX_WRITE_OPERATIONS_PER_MINUTE and MAX_WRITE_OPERATIONS_PER_HOUR quotas. You will need to have some other criteria for writing to storage.sync. Perhaps you could temporarily store the value in storage.local and only to storage.sync every couple of minutes.
I have my front end script which has the following jQuery code:
$.get("/backend/post.php", {
title: title,
message: post,
stick: sticky
}, function (output) {
alert("Call Back");
}
}, "json");
stick is a boolean value, the other two are strings. I've confirmed that they are in fact set. Now on the backend page, using $_GET, title and, message and being passed, but $_GET['stick'] is returning empty, and the PHP function gettype() is telling me it is NULL.
In request to one of the comments:
sticky comes from a form, it's a check box and I just select it with this code:
var sticky = $("input[name=sticky]").attr('checked');
When I use alert() to output the value of sticky, it will return true/false depending on what was selected.
Why is this boolean value not being passed? The JSON site tells me you can have the boolean values true/false in it. But it is not working here for some reason.
I can't be entirely sure because I haven't tested it myself, but I think this is related to how GET requests transfer as strings. Try something like this:
var sticky = $("input[name=sticky]").attr('checked')?"true":"false";
$.get("/backend/post.php", {
title: title,
message: post,
stick: sticky
}, function (output) {
alert("Call Back");
}
}, "json");
It's entirely likely that this won't work, but give it a try.
If in a form an input does not have a value it will not be sent as a parameter. So the absence of of a $_GET['stick'] is equivalent to the query string parameter stick=false. So if you must have a parameter:
var sticky = 'true';
if($("input[name=sticky]").not(':checked')) {
sticky = 'false';
}