Javascript Shopping list declaring let - javascript

Why this program doesn't work when i try declaring let inputError globally like the rest lets or I write let before inputError in function?
I don't understand why it only works when it is declaring inside the function without let, const.
let ul_var;
let shoppingArray = ["Mleko", "Jajka", "Piwo"];
let new_item_form_var;
>>>> let inputError; <<<< //without it works
document.addEventListener("DOMContentLoaded", () => {
ul_var = document.getElementById("shopping");
>>>> let <<<< inputError = document.getElementById('inputError');
new_item_form_var = document.getElementById("new_item_form");
new_item_form_var.addEventListener("submit", (event) => {
event.preventDefault();
let input = event.target.elements[0];
if (input.value.length > 2 && !input.value.startsWith(' ')) {
addListItem(input.value);
input.value = '';
input.classList.remove('input-danger');
inputError.innerText = '';
} else {
inputError.innerText = 'Nazwa nie spelnia kryteriow';
input.classList.add('input-danger')
}
});
for (let x of shoppingArray) {
addListItem(x);
}
});
function addListItem(y) {
let li_var = document.createElement("li");
li_var.innerText = y;
ul_var.appendChild(li_var);
}

If you have one let inputError then you can't have another one, because you can't declare the same variable several times. You should instead write:
let inputError;
document.addEventListener("DOMContentLoaded", () => {
ul_var = document.getElementById("shopping");
inputError = document.getElementById('inputError'); // no let
or this, if you don't use inputError outside of the event listener:
// no 'let inputError;'
document.addEventListener("DOMContentLoaded", () => {
ul_var = document.getElementById("shopping");
let inputError = document.getElementById('inputError');

Related

How to get variable in set method

I have an issue with getting a variable in a setter method when I create a class.
In the picture above you can see my method "set quest" returns this (num 1) instead of this.questId (num 2) . How can I get this.questId in "set" and what I am doing wrong? Thank you in advance.
class TestItem {
constructor(testItem) {
this.quest = testItem.quest;
this.answList = testItem.answList;
this.questId = testItem.id;
}
set quest(value) {
console.log(this , this.questId);
let questItem = document.createElement('div');
questItem.classList.add('questItem');
questItem.textContent = `${this.questId}. ${value}`;
this._quest = questItem;
}
set answList(value) {
this._answList = value.map((item, i) => {
let answItem = document.createElement('span');
answItem.classList.add('answItem');
answItem.setAttribute('data-value', item.val);
answItem.textContent = item.answ;
return answItem;
});
}
getQuestBlock() {
let questBlock = document.createElement('div');
questBlock.classList.add(`quest${this.questId}`);
questBlock.append(this._quest);
this._answList.forEach(item => questBlock.append(item));
console.log(questBlock);
return questBlock;
}
}
function createTest(testData) {
let testContainer = document.querySelector('#testContainer');
testData.forEach((item, i) => {
let testItem = new TestItem(item);
let questBlock = testItem.getQuestBlock();
testContainer.append(questBlock);
});
}
document.addEventListener("DOMContentLoaded", createTest.bind(this ,testData));

Intended of Load JQuery once function in other js file executed completely

I am fetching some data from the database and based on retrieved data HTML is being rendered on the browser. Once the HTML is being rendered then I want to apply JQuery on them. following is my code
fetch_items.js File
async function itemsWithAllDetails() {
let responseData = await retrieveItems();
let itemsWithSizes = await getSizes(responseData);
let itemsWithImages = await getImages(itemsWithSizes);
let itemsWithColors = await getColors(itemsWithImages);
let filtered_items_sales = filterItems(itemsWithColors, 'sales_section');
renderItems(filtered_items_sales, "sales_section");
let filtered_items_boys = filterItems(itemsWithColors, 'BOYS');
renderItems(filtered_items_boys, "boys_section");
let filtered_items_girls = filterItems(itemsWithColors, 'GIRLS');
renderItems(filtered_items_girls, "girls_section");
let filtered_items_bboys = filterItems(itemsWithColors, 'BABY BOYS');
renderItems(filtered_items_bboys, "baby_boy_section");
let filtered_items_bgirls = filterItems(itemsWithColors, 'BABY GIRLS');
renderItems(filtered_items_bgirls, "baby_girl_section");
let filtered_items_men = filterItems(itemsWithColors, 'MEN');
renderItems(filtered_items_men, "men_section");
let filtered_items_women = filterItems(itemsWithColors, 'WOMEN');
renderItems(filtered_items_women, "women_section");
}
itemsWithAllDetails();
JQuery File
$(document).ready(function () {
$("button.increament").click(function () {
let x = $(this).siblings("input").val();
if (x == "") {
x = 0;
}
x = parseInt(x);
if (x >= 5) {
alert("You can not order more than 5");
}
else {
$(this).siblings("input").val(x + 1);
}
});
$("button.decreament").click(function () {
let x = $(this).siblings("input").val()
if (x >= 1) {
$(this).siblings("input").val(parseInt(x) - parseInt(1));
}
});
// Increment Decrement Buttons End Here
});
Why events are not working? What I am doing wrong/missing here?
i did it by excluding events from $(document).ready();
Then include them in another function and called it from itemsWithAllDetails function at the end.

'This' undefined in parsing the xml API using react

I have been trying to make a data from XML clickable in react. This is working in one of the function but gives an error when it is called in an another function.
Shows = Unhandled Rejection (TypeError): Cannot read property 'getAuthArticles' of undefined
I have tried using bind(this). I am already using the arrow functions
getData() {
fetch(`http://export.arxiv.org/api/query?search_query=ti:${'therapy'}&sortBy=lastUpdatedDate&sortOrder=ascending`).then(data=>data.text()).then(str => (new window.DOMParser()).parseFromString(str, "text/xml")).then(data => {
var entry = data.getElementsByTagName("entry");
let elems = []
for(let i=0;i<entry.length;i++){
console.log(entry);
let elem = <div key={i} id={entry[i].getElementsByTagName("id")[0].textContent} onClick={this.handleChange}>{entry[i].getElementsByTagName("title")[0].textContent}</div>;
elems.push(elem);
}
console.log(elems)
this.setState({data: elems});
})
}
/* */
handleChange(evt) {
console.log(evt.target.id)
var res = evt.target.id.split("/");
var id = res[5]
fetch(`http://export.arxiv.org/api/query?id_list=${res[4]}/${id}`)
.then(data=>data.text()).then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
.then(data => {
var summ = data.getElementsByTagName("summary");
let auth = data.getElementsByTagName("author");
let elems1 = [];
let name = [];
console.log(auth)
for (let i = 0; i < auth.length; i++ ){
console.log(auth[i].textContent);
console.log(auth[i].getElementsByTagName("id"));
let elem1 = <div key={i} id={auth[i].textContent} onClick={this.getAuthArticles.bind(this)}>{auth[i].textContent}</div>;
name += auth[i].textContent;
// elems1.push(elem1);
// console.log(elem1)
}
document.getElementById("demo").innerHTML = summ[0].textContent + name;
// window.history.pushState({}, "page 2", "bar.html");
// this.setState({data: elems1});
})
}
getAuthArticles(evt) {
console.log(evt.target.id)
let auth_name = evt;
fetch(`http://export.arxiv.org/api/query?search_query=${auth_name}`)
.then(data=> data.text()).then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
.then(data => {
var arti = data.getElementsByTagName("title");
let titles = []
for(let i=0;i<arti.length;i++){
let elem = <div key={i} id={arti[i].getElementsByTagName("id")[0].textContent}>{arti[i].getElementsByTagName("title")[0].textContent}</div>;
titles.push(elem);
}
console.log(titles)
})
}
I see you're using normal function and you missing bind(this) in getData()
onClick={this.handleChange}
// should change to
onClick={this.handleChange.bind(this)}
And make sure you bind(this) for getData()
It will easier with arrow function like
handleChange = (evt) => {}
you don't need to bind(this) for arrow function

Passing Arguments to function in javascript

I have a function(case) as below,
let fn = (() => {
let ab = {};
let register = () => {
console.log("hello" + ab[x])
};
return (x,y) => {
ab[x] = y;
return register();
};
})();
this function is working only when I call as below,
let x = 'key';
let y = 'value';
fn(x,y);
Is there any chance to call directly like
fn('key', 'value');
what changes I have to make in function to call directly
The problem is your register function doesn't know about x. You need to pass it through from your previous function:
let fn = (() => {
let ab = {};
let register = (x) => {
console.log("hello" + ab[x])
};
return (x,y) => {
ab[x] = y;
return register(x);
};
})();
fn("key", "value");
I believe this is because you aren’t defining the parameters in the functions.
let fn = ((x,y) => {
let ab = {};
let register = () => {
console.log("hello"+ab[x])};
return (x,y) => {
ab[x]=y;
return register();
};
})();

Evaluating JavaScript expression with a worker

I need to evaluate JavaScript expressions, in a browser, Chrome. To make it safe, I use a Blob and a Worker running my evaluator, until it posts back the result of a timeout cancels the wait. This is working fine. I also need to support an environment for my JavaScript. I do this as below:
function evalWorker () {
let postResponse = function(expr, ...) {
let presets = `var EnvObject = {};
EnvObject.platform = "Chrome";
EnvObject.pasteboard = "${clipboard}";
EnvObject.baseDate = new Date();
...
EnvObject._output = "";
EnvObject.appendOutput = (str) => {EnvObject._output += str; };
`
postMessage(eval(presets + expr));
};
onmessage = function(e) {
postResponse(e.data['expression'], e.data['clipboard'], ...);
}
}
My problem is that if _output is not empty, I need to return that - _output instead of the evaluated expression, as in
EnvObject.appendOutput('hello');
var a = 0;
++a;
Should return hello; while without appendOutput, it should return 1.
How would I go about something like this?
#Bergi had the right idea with pushing the scope out. The below works.
function evalWorker () {
let postResponse = function(expr, TextExpander) {
let result = eval(expr);
if (EnvObject._output && EnvObject._output.length) {
postMessage(EnvObject._output);
} else {
postMessage(result);
}
};
onmessage = function(e) {
var EnvObject = {};
EnvObject.platform = "Chrome";
EnvObject.pasteboardText = e.data['clipboard'];
...
EnvObject._output = "";
EnvObject.appendOutput = function(str) {EnvObject._output += str; };
postResponse(e.data['expression'], EnvObject);
}
}

Categories

Resources