I've tried to decode the code I've been studying for a while. But, probably, because of my beginner mindset, so I still cannot understand how it works.
Here's my question. The word 'text' inside function addTodo('text').
Where does it come from? or it's declared as its own entity for itself. And what is it for?
Thank you in advance
function addTodo(text) { // The 1st 'text'
const todo = {
text, // the 2nd 'text'
checked: false,
id: Date.now(),
};
todoItems.push(todo);
renderTodo(todo);
}
const form = document.querySelector('.js-form');
form.addEventListener('submit', event => {
event.preventDefault();
const input = document.querySelector('.js-todo-input');
const text = input.value.trim(); // the 3rd text
if (text !== '') {
addTodo(text);
input.value = '';
input.focus();
}
});
function addTodo(text) is the signature for the 'addTodo' function. It takes one argument, which is called text.
This argument is then used within the function. It's provided as the value of a property to an object called todo (this is a bit of a short-hand in JavaScript)
The 'third' use of text, is created as result of applying trim to the value property of the input. This text could have been called something else.
This use of text is then passed to the function we previously talked about, assuming it's not empty.
You could equally write the code as follows - it would work just the same
function addTodo(textForTheTodo) { // The 1st 'text'
const todo = {
text: textForTheTodo, // the 2nd 'text'
checked: false,
id: Date.now(),
};
todoItems.push(todo);
renderTodo(todo);
}
const form = document.querySelector('.js-form');
form.addEventListener('submit', event => {
event.preventDefault();
const input = document.querySelector('.js-todo-input');
const textFromTheInput = input.value.trim(); // the 3rd text
if (textFromTheInput !== '') {
addTodo(textFromTheInput);
input.value = '';
input.focus();
}
});
Related
I am defining my variable as array and pushing values inside it.
When I try to access this variable inside another method and apply push function on it, It says, Push is not defined.
When I check the typeof of this variable it shows as String.
Any suggestions?
recipients = [];
....
handleEmailChange(event) {
const {name , value , dataset: {recipientIndex} } = event.target;
this.toAddresses[recipientIndex][name] = value;
}
handleChange(event) {
this.recipients = event.detail.value;
}
handleSend(event){
this.toAddresses.forEach ( (address) => {
const email = address.emailAddress;
this.recipients.push(email);
I suppose it caused because in the function handleChange you wrote this.recipients = event.detail.value where event.detail.value is probably a string type.
I would like to set a timer for the action function. The rule is: when the selected text does not change for 3 seconds, we run the function action with the selected text.
I tried the following code in the playground https://microsoft.github.io/monaco-editor/playground.html, it did not work. When I changed the selected text very quickly, their actions were not cancelled.
Could anyone help?
const editor = monaco.editor.create(document.getElementById('container'), {
value: '1+2+3+4+5+6+7',
language: 'javascript'
});
function action(x) {
console.log("action", x)
}
let myTimeout
editor.onDidChangeCursorSelection((e) => {
clearTimeout(myTimeout)
console.log("cleared", myTimeout)
let selectedText = editor.getModel().getValueInRange(editor.getSelection())
if (selectedText != "") { // if we are already in this event, the selected text must change
myTimeout = setTimeout(action(selectedText), 3000);
console.log("set", myTimeout, selectedText)
}
})
Edit 1: My component is a class component, so I cannot use hook calls.
You can use lodash's debounce to achieve the effect you want. And use useCallback to make sure you get the same instance of function. I think an implementation like this might work:
import _ from 'lodash';
...
const debouncedAction = _.debounce(action, 3000).bind(this);
editor.onDidChangeCursorSelection((e) => {
let selectedText = editor.getModel().getValueInRange(editor.getSelection())
if (selectedText != "") { // if we are already in this event, the selected text must change
debouncedAction(selectedText);
}
})
I used this as a reference.
setTimeout takes function as input, while you have called it. I think the following code works well.
const editor = monaco.editor.create(document.getElementById('container'), {
value: '1+2+3+4+5+6+7',
language: 'javascript'
});
function action(x) {
console.log("action", x)
}
let myTimeout
editor.onDidChangeCursorSelection((e) => {
clearTimeout(myTimeout)
let selectedText = editor.getModel().getValueInRange(editor.getSelection())
if (selectedText != "") {
// "action" is called inside a function
myTimeout = setTimeout(() => action(selectedText), 3000);
}
})
So my goal was to reverse this jquery into javascript. Here is the jquery
create: function (e) {
var $input = $(e.target);
var val = $input.val().trim();
if (e.which !== ENTER_KEY || !val) {
return;
}
this.todos.push({
id: util.uuid(),
title: val,
completed: false
});
$input.val('');
this.render();
},
Now here is the same code that I converted into javascript
create: function (e) {
var input = e.target.value;
var val = input.trim();
if (e.which !== ENTER_KEY || !val) {
return;
}
this.todos.push({
id: util.uuid(),
title: val,
completed: false
});
val;
this.render();
},
So my Javascript code works and I understand 90% of it, but what I don't get is the 2nd to last line that just says "val;"
I went through the debugger and tried to understand it, but I don't get the reason it's placed there and why it's even necessary?
The goal is whenever I input a value to my todo-list, it will show up on my screen. The code works fine, but I don't understand the purpose of the "val;"?
Wouldn't the this.todos.push automatically add the value to my array? Or why wouldn't I add "return val;" instead?
I guess that previous $input.val(''); was used to empty the input field after pushing its value to the array, but in your js code it is useless that val; statement.
Furthermore, the jquery code $input.val(''); refers to the input DOM element, however in your js code the val statement just points to a local variable of your function. If you want to replicate the previous behaviour you should do something like this: input='' instead of the val;
I have a coding challenge, which am sure am getting it right , but the challenge requires that certain steps need to be in account before moving forward. And i seem to be skipping a step which is to de-structure a value from a target of an event(hope am saying it right)
The question is to get the expected event parameter to the target property with a de-structure.
Is my code wrong?
const displaySelectedUser = (event) => {
var newcal = event.target.value;
console.log(newcal);
console.log((event.target.value));
var user = getSelectedUser(newcal);
var properties = Object.keys(user);
console.log(properties);
properties.forEach(prop => {
const span = document.querySelector(`span[data-${prop}-value]`);
if (span) {
span.innerText = user[prop];
}
});
};
It's not wrong - but the only practical opportunity you have for destructuring is here:
var newcal = event.target.value;
Do this:
var { target: { value: newcal } } = event;
Because you're not using the other properties of event, you could move this up to the function declaration instead:
const displaySelectedUser = ({ target: { value: newcal } }) => {...}
Now newcal will already be defined as event.target.value in your function.
My config (as an example) is setup like so:
this.config = [
{
element: '#Amount',
type: "money",
notNull: true,
error: "You must specify an amount"
},
{
element: '#Type',
type: "string",
notNull: true,
error: "You must specify whether you want a 6 week loan or a 12 month loan"
}
]
I have a bind function that should bind a validation function to each element in the list:
this.bind = function () {
for (var i = 0; i < _this.config.length; i++) {
var arr = _this.config[i];
console.log('Binding ' + arr.element + ' to single input validation')
// bind single validation to each element
$(document).on('keyup', arr.element, function () {
_this.validate(arr.element)
})
}
}
And in the console I am presented with:
Binding #Amount to single input validation
Binding #Type to single input validation
Binding #LoanPurpose to single input validation
The config actually consists of 47 elements, however I am certain that only the last bind remains after iterating through the config so it's as if it's replacing the previous bind each time.
Any pointers would be greatly appreciated
Thanks
This is a classic javascript error. Your nested keyup handler function references a variable arr, which is getting overwritten by the for loop every iteration. So when the keyup handler finally does execute, it's using the arr that is referencing the last element in this.config array.
This link explains why it's bad to make functions within loops. And provides a solution for it.
Here's how your code should probably look:
this.bind = function () {
for (var i = 0; i < _this.config.length; i++) {
var arr = _this.config[i];
console.log('Binding ' + arr.element + ' to single input validation')
// bind single validation to each element
_this.makeBind(arr.element)
}
}
this.makeBind = function (el) {
$(document).on('blur', el, function () {
_this.validate(el)
})
}
config.forEach(function(item) {
$(document.body).on('keyup', item.element, function() {
validate(item, this.value)
});
});
You can do something like the preceding to pass both the item, and the input's current value to the validate function