I am looking for a way to make my JS errors handling function dynamic, now i am checking each possible error seperately, the function code looks like this.
function handleErrors(errors){
if (errors.nameError){
nameEl.classList.add('is-invalid');
nameEl.nextElementSibling.innerHTML = errors.nameError;
}
if (errors.surnameError){
surNameEl.classList.add('is-invalid');
surNameEl.nextElementSibling.innerHTML = errors.surnameError;
}
if (errors.emailError){
emailEl.classList.add('is-invalid');
emailEl.nextElementSibling.innerHTML = errors.emailError;
}
if (errors.passwordError){
passwordEl.classList.add('is-invalid');
passwordEl.nextElementSibling.innerHTML = errors.passwordError;
}
if (errors.passwordConfirmError){
passwordConfirmEl.classList.add('is-invalid');
passwordConfirmEl.nextElementSibling.innerHTML = errors.passwordConfirmError;
}
if (errors.phoneError){
phoneEl.classList.add('is-invalid');
phoneEl.nextElementSibling.innerHTML = errors.phoneError;
}
if (errors.addressError){
addressEl.classList.add('is-invalid');
addressEl.nextElementSibling.innerHTML = errors.addressError;
}
}
Basically each time i have two variables, i am checking if there exists specific error object and if it exists i am printing that error value to the corresponding HTML element. What would be the way to write a function that would check all errors dynamically. Thank you for your thoughts.
You could do it like that:
var errorsAndElements = {
nameError: nameEl,
surnameError: surNameEl,
emailError: emailEl,
passwordError: passwordEl,
passwordConfirmError: passwordConfirmEl,
phoneError: phoneEl,
addressError: addressEl
};
function handleErrors(errors){
var possibleErrors = Object.keys(errorsAndElements);
for (var i = 0; i < possibleErrors.length; i++) {
var errorName = possibleErrors[i];
if (errors[errorName]) {
var errorElement = errorsAndElements[errorName];
errorElement.classList.add('is-invalid');
errorElement.nextElementSibling.innerHTML = errors[errorName];
}
}
}
It stores the possible errors and according elements in an object, then it iterates over that object and checks if the error exists in the passed error object. If the error exists, it takes the element and displays it.
Related
I'm quite new to javascript and i'm trying to send one variable to a function, call an api from there and get the stats back into module.exports but I cant seem to figure it out....
Here's basically how my code is built:
function stuff(userArg) {
(calling api magic here)
var index = -1;
for(var i = 0; i < Object.keys(res['data']['playerstats']['stats']).length; i++) {
if(res['data']['playerstats']['stats'][i]['name'] === 'deaths') {
index = i;
var userDeaths = res['data']['playerstats']['stats'][index]['value'];
break;
}
}
return userDeaths;
}
module.exports = {
name: 'table',
description: '.....'
async run(messages, args) {
const userArg = args.join(" ");
stuff(userArg);
console.log(userDeaths);
}
}
It seems like it should work but I cant get it to work and its driving me mad... If anyone knows the reason i'd greatly apppreciate it!
I don't think this has anything to do with module exports. You just forgot to assign the return value of the stuff() call to a local variable. Notice that userDeaths is not a global variable, you declared it in stuff, which means you cannot use it in run.
function run(messages, args) {
const userArg = args.join(" ");
const userDeaths = stuff(userArg);
// ^^^^^^^^^^^^^^^^^^
console.log(userDeaths);
}
i have an object that stores a table for converting a json response in a user readeable text. The thing is, the same text applies for multiple json conditions.
I want to know if there's a way to set the same value for 2 different Id's in a object.
Like, instead of:
var msg = {
"error_code1": "user_msg",
"error_code2": "user_msg",
}
Something like this
var msg = {
"error_code1" && "error_code2": "user_msg",
}
Is it possible?
First approach is using "getter" functions to reference the initial object:
var errorBindings = {
'errorCode101': 'Unauthorized request',
get 'errorCode102'() { return this.errorCode101; },
get 'errorCode103'() { return this.errorCode101; },
'errorCode104': 'All fields are required',
get 'errorCode105'() { return this.errorCode104; },
};
console.log(errorBindings.errorCode103); // "Unauthorized request"
Second approach is using an anonymous function with referencing properties from which we should borrow the needed value:
var messages = function(o) {
o.errorCode101 = 'Authorization error!';
o.errorCode102 = o.errorCode101;
o.errorCode103 = o.errorCode101;
o.errorCode104 = 'All fields are required';
return o;
}({});
console.log(messages.errorCode101); // "Authorization error!"
console.log(messages.errorCode103); // "Authorization error!"
What about:
var msg = {};
msg['a'] = msg['b'] = 'value';
But for such simple cases I prefer to repeat myself instead of doing premature optimizations.
Unfortunately in JSON all keys must be strings so what you are attempting will not work.
As a work around I can suggest storing a reference to the value of the user_msg and assigning it to each error code key.
For example:
var storedMessage = "user_msg";
var msg = {
"error_code1": storedMessage,
"error_code2": storedMessage
}
Let me know if you have any questions.
The following code gives me the error "Cannot read property PERSON1 of null". If I comment out the line where I try to assign the dynamic variable and uncomment the alert line it pops up alerts with each successive person's name.
function fillInternalRepData() {
var internalRepList = null;
console.log("Querying Table for internal reps");
queryTable(//..blabla..//, "false", function (callbackResp) {
internalRepList = callbackResp;
// alert("TRIGGERED"); //WORKS
// alert(internalRepList.length); //WORKS
angular.forEach(internalRepList, function (rep) {
repName = rep.such;
$scope.internalReps[repName].such = repName;
//alert(repName); //WORKS WHEN LINE ABOVE IS COMMENTED OUT
});
}); //get list of internal reps
I simply want to create/add to the $scope.internalReps object so that I can add stuff to it like $scope.internalReps.PERSON1.Name = "Whatever"; $scope.internalReps.PERSON1.Salary = 100000;
Try adding an empty object for the "internalReps" before your forEach loop. It doesn't look like you've declared the object yet, so it can't dynamically add to a null object.
$scope.internalReps = {};
angular.forEach(internalRepList, function (rep) {
repName = rep.such;
$scope.internalReps[repName] = {};
$scope.internalReps[repName].such = repName;
//alert(repName);
});
var internalReps = {};
angular.forEach(internalRepList, function (rep) {
repName = rep.such;
internalReps[repName] = { such: "" };
internalReps[repName].such = repName;
//alert(internalReps[repName].such);
});
That worked. Thanks for the help!
What am I doing wrong, and how can one pass variables to a different function within the same wrapping variable/function.
Example:
function customFunctionWrap(){
this.myVar1 = 0;
this.getCurrentPosition = function(){
if (navigation.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){});
}
},
this.doSomething = function(){ // Works
//Do something, return
this.callWithParams(); //Works
},
//If I remove passing in 'value1',calling it elsewhere works
this.doSomethingWithParams = function(value1){
//Use value1
//Return
},
this.callWithParams = function(){
var value1 = 'xyz'; //Is a variable that changes based on some DOM element values and is a dynamic DOM element
this.doSomethingWithParams(value1); //THROWS TYPEDEF ERROR: this.doSomethingWithParams is not a function
this.getCurrentPosition();
}
};
var local = new customFunctionWrap();
local.doSomething(); //WORKS
I know there is another way to do it and then directly use customFunctionWrap.callWithParams(), but am trying to understand why the former approach is erroring out.
var customFunctionWrap = {
myVar1 : 0,
callWithParams : function(){
}
}
What JS sees:
var customFunctionWrap = (some function)()
returned function is fired, because the last (), so it has to yield/return something, otherwise, like in your code it is "returning" undefined.
So your given code does not work.
The very first fix is to delete last 2 characters from
var customFunctionWrap = (some function)()
to make it return constructor.
I am making a simple hmtl/js game. I'd like to have all the data of the Game in DataofGame. It is like tennis, it is simpler than tennis: there is only set and match. changeinSet is called on click.
But I think i have a problem with private variable so it doesn't work.
Uncaught TypeError: Cannot read property 'WordsoftheGame' of undefined
//Added
document.getElementById('playboutton').addEventListener('click', newGame);
function newGame() {
var DataofGame = new newGameData();
}
// New game
function newGameData() {
this.pointTeam1 = 0;
this.pointTeam2 = 0;
this.WordsoftheGame = ShuffleListe();
this.ASet = new aSet();
}
//How the set is manage ********************
function aSet() {
var oneWord = DataofGame.ListeMot;
// display the word and delete it from the list
document.getElementById('jouer').innerHTML = oneWord[0];
DataofGame.WordsoftheGame.shift();
this.turn = true;
this.score = 0;
}
function changeinSet() {
DataofGame.ASet.score += 1;
//This is the other team's turn:
DataofGame.ASet.turn = !DataofGame.ASet.turn;
};
//shuffle liste
ListOfWords = ['Artiste', 'Appeler', 'Cheval', 'Choisir', 'Ciel', 'Croire', 'Dormir'];
function ShuffleListe() {
data = shuffle(ListOfWords);
return data;
}
function newGameData(){
this.pointTeam1=0;
this.pointTeam2=0;
this.WordsoftheGame= ShuffleListe();
this.ASet=new aSet();
}
//How the set is manage ********************
function aSet(){
var oneWord=DataofGame.ListeMot;
// display the word and delete it from the list
document.getElementById('jouer').innerHTML=oneWord[0];
DataofGame.WordsoftheGame.shift(); // << DataofGame not assigned yet
this.turn=true;
this.score=0;
}
Here when you're accessing DataofGame, it's not yet assigned because you're inside the constructor when calling aSet().
What you want to achieve is not completely clear, but if it's adding an ASet method to your object, you could write something like this:
function newGameData(){
this.pointTeam1=0;
this.pointTeam2=0;
this.WordsoftheGame= ShuffleListe();
this.ASet = function() {
// your code
};
}
NB your coding style for names is a bit messy, you should use uppercases consistently. The usage is to start constructor names with uppercases, the rest in lower cases.
You can let the function return an object with the data or just set the object.
function newGameData(){
return {
pointTeam1 : 0,
pointTeam2 : 0,
WordsoftheGame : ShuffleListe(),
ASet : new aSet()
}
}
But I would recommend to search for how to work with objects in javascript. Maybe this helps:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript