Accessing & Manipulating DOM for JS Module - javascript

I'm new to importing modules in ES6. I have a simple module with a function for creating and appending an HTML element.
I am able to call and pass arguments to the function, however, I cannot read any properties from the DOM. I am receiving errors such as this:
Uncaught TypeError: Cannot read properties of null (reading 'parentNode')
I have simplified my code below:
main.js
import * as watm_fn from "./modules/functions.js";
document.addEventListener("DOMContentLoaded", function (event) {
watm_fn.createToggle("#container");
}
functions.js
export function createToggle(elm) {
const toggleElementID = document.getElementById(elm);
const languageToggle = document.createElement("select");
toggleElementID.parentNode.replaceChild(languageToggle, toggleElementID);
}
I get a similar error when trying to return the innerHTML of toggleElementID
Is accessing and manipulating the DOM via an imported module possible? And if so, what am I doing wrong?
(I am not using node or jquery in this project)

Well I feel dumb. I'm used to coding in jQuery where you include the "#" in front of your IDs, but I forgot that getElementById does not require that. Removing that from my passed argument resolved the issue.

Uncaught TypeError: Cannot read properties of null (reading 'parentNode')
This error suggests that the below line is failing toggleElementID is null:
toggleElementID.parentNode.replaceChild(languageToggle, elm);
Why is toggleElementID null ?
Look at the code searching for the element
const toggleElementID = document.getElementById(elm);
As per getElementById
An Element object describing the DOM element object matching the specified ID, or null if no matching element was found in the document.
So there is no matching element found with the supplied elm id.

Related

Unable to access a property on a variable within a function. Uncaught TypeError:

I have a trivia app that is importing an array of objects called "questions". I have used getElementById to capture each of the buttons, and also added click event listeners for the "checkAnswer" function below.
However, I am getting the error: Uncaught TypeError: can't access property "correct", answer is undefined. This happens with any button I click.
I am using type="module" within the script tag in the HTML file.
The buttons are populating the correct text, but are not console logging any text like it should.
"randomQuestion" is a global variable that is being generated in another function within the same file. This is what it looks like:
randomQuestion = questions[Math.floor(Math.random()*questions.length)];
function checkAnswer(bntIndex) {
answer = randomQuestion.answers[bntIndex];
if (answer.correct === true) {
console.log("Correct!");
} else {
console.log("Incorrect");
}
}
It's rather a warning than an error.
You are getting those because you don't export this function and also don't use it anywhere

Template.QuerySelector inside Template Tag Not Working

I am trying to render a jsonTree instead of just json text and have the following javascript code to do it (Note: It is in a switch statement):
case 'LONGTEXT':
this.isLongText = true;
var wrapper = this.template.querySelector('[data-id="tree_destination"]');
var treedata = JSON.parse(this.value);
var tree = jsonTree.create(treedata, wrapper);
break;
Here is the HTML:
<template if:true={isLongText}>
<div data-id="tree_destination">This is my tree.</div>
</template>
I am quite new to all of this, so sorry if there is a trivial mistake. The library I am trying to use to get the tree can be found at this link: https://github.com/summerstyle/jsonTreeViewer
or https://www.npmjs.com/package/json-tree-viewer
The error I am getting is "Unhandled Rejection (TypeError): Cannot read property 'appendChild' of null" and I am getting it on the jsonTree.create() line. I am almost 100% sure that it has to do with the wrapper, but I am not completely sure. When I do console.log of the wrapper, though, it returns null.
Thanks for the help in advance!
template elements aren't standard elements. To access their contents, you use the content property, which is a DocumentFragment. So change your querySelector to:
var wrapper = this.template.content.querySelector('[data-id="tree_destination"]');
// −−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^
const template = document.querySelector("template");
const div = template.content.querySelector('[data-id="tree_destination"]');
console.log(div);
<template if:true={isLongText}>
<div data-id="tree_destination">This is my tree.</div>
</template>
Note that I can't guarantee that particular library is happen to render into a disconnected element, but this does solve the querySelector problem. :-)

What is the error OpenQA.Selenium.WebDriverException : javascript error: document.getElementByName is not a function

I got a error in executing the below line of code
driver = new ChromeDriver(#"C:\Users\hp\Documents\Driver");
driver.Navigate().GoToUrl("http://demo.guru99.com/v3/");
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("document.getElementByName('uid').value ='mngr303517'");
js.ExecuteScript("document.getElementByName('password').value='ujudysY'");
js.ExecuteScript("document.getElementByName('btnLogin').click()");
I got the error At line 3
document.getElementByName is not a function (Session info: chrome=87.0.4280.141)
what is the reason for it?
The JavaScript method is document.getElementsByName(...) (plural - Elements not Element).
This method returns a collection of elements, not a single element.
js.ExecuteScript("document.getElementsByName('uid')[0].value ='mngr303517'");
Be sure to access the [0] index of the collection before calling the value property.
It might be a little cleaner to use document.querySelector instead:
js.ExecuteScript(#"document.querySelector(""[name='uid']"").value ='mngr303517'");
js.ExecuteScript(#"document.querySelector(""[name='password']"").value='ujudysY'");
js.ExecuteScript(#"document.querySelector(""[name='btnLogin']"").click()");

Magento 2 error in swatchRenderer.js

I have overridden magento SwatchRenderer.js file in app\code\Mydirectory\CustomSwatches\view\frontend\web\js\SwatchRenderer.js.
My problem is I get an error in my product page load:
Uncaught TypeError: Cannot read property 'updateData' of undefined
I found out that data('gallery') on SwatchRenderer.js's following function is undefined.
updateBaseImage: function (images, context, isProductViewExist) {
var justAnImage = images[0];
if (isProductViewExist) {
context
.find('[data-gallery-role=gallery-placeholder]')
.data('gallery')
.updateData(images);
} else if (justAnImage && justAnImage.img) {
context.find('.product-image-photo').attr('src', justAnImage.img);
}
}
I checked a Magento 2 demo site. On that site the above data attribute is set as a JavaScript object. The target element is a div with the above attribute. But in my site it is undefined and obviously I think that data attribute is not set on my site. Can anyone help me to find the setter function/view/file for above element? Any help would be appreciated. Thanks.
What theme was used in your Magento instance? Did you rename the container class names?
One interesting piece of code is found on line 202 of the SwatchRenderer.js file. Under the _create function you will find the initialization of the gallery variable as seen here
You will notice that it finds the element with the data-gallery under the .column.main element. Thus, as missing column main element would return an empty response.
I found a pretty efficient way to fix this:
Copy the /vendor/magento/module-swatches/view/frontend/web/js/swatch-renderer.js-file to app/design/YourName/YourTheme/Magento_Swatches/web/js/swatch-renderer.js and replace the code inside updateBaseImage() (line ~1152) with the following:
updateBaseImage: function (images, context, isInProductView, eventName) {
var gallery = context.find(this.options.mediaGallerySelector).data('gallery');
if (eventName === undefined && gallery !== undefined) {
this.processUpdateBaseImage(images, context, isInProductView, gallery);
} else {
context.find(this.options.mediaGallerySelector).on('gallery:loaded', function (loadedGallery) {
loadedGallery = context.find(this.options.mediaGallerySelector).data('gallery');
this.processUpdateBaseImage(images, context, isInProductView, loadedGallery);
}.bind(this));
}
},
The trick is: this method doesn't wait for the gallery to be fully loaded, while this event (gallery:loaded) is readily available. By adding this to the method, it works fine.
I just hope that the Magento Dev's pick up on this and implement this in the core-code.

ExtJS 4 Object.prototype fail

have a bit problem to use prototype while using framework ExtJS version 4.1.1.
At first I made my prototypings before I load ExtJS.
On "Array.prototype.xyz" and "String.prototype.xyz" all work fine.
Bot on "Object.prototype.xyz" there is a bad behavior in mixin inclusion of ExtJS.
Example my test code:
Object.prototype.doSomething = function() {
console.log('I do it!');
}
var a = {};
a.doSomething();
Error message from ExtJS:
Uncaught TypeError: Cannot read property '$childEls' of undefined
And break.
And:
- Yes. Without "Uncaught TypeError: Cannot read property '$childEls' of undefined" it work
fine.
- No. I use not oter mixins currently.
- Yes. I try to use only one dummy panel Component.
Question: Is there a simple solution to prototype on Object class-object?
The problem stems from one of the fundamental methods of the Ext JS library: Ext.merge
Proving this is very simple:
Object.prototype.doSomething = function(){ console.log("Does something"); };
var emptyObj = {};
console.log(emptyObj.hasOwnProperty("doSomething")); // Prints "false"
var mergeObj = Ext.merge({}, {a: "b"});
console.log(mergeObj.hasOwnProperty("doSomething")); // Prints "true"
Basically, every time Ext.merge (or Ext.apply) is called with an object literal your prototype method is "promoted" up the prototype chain. When you go to create a panel (or any component, really) the class mixin object is merged with its prototype's mixin object. Since a mixin is defined as an object literal in the class definition, your "doSomething" method is promoted.
Then in Ext.util.ElementContainer#getClassChildEls, the mixin object is iterated over assuming each property is an existing class and tries to access mixins[name].self.$childEls (where mixins[name] is your "doSomething" method). Your method doesn't have a self property so accessing $childEls throws the error.
If you need an object available on every object, write it as a static method like Object.doSomething or even Ext.Object.doSomething.

Categories