Cannot use object key to reference method in Javascript - javascript

I have a set of methods for validating input stored in a variable val such that I can call them like val.email or val["email"]. I'm trying to create a general function that will take an object and apply the validation function to each value based on the keys. My attempt is as follows:
const validateInput = data => {
let errors = {};
const keys = Object.keys(data);
keys.map(key => {
const error = val[key](data[key]);
errors = { ...errors, ...error };
});
return errors;
};
I get this error:
TypeError: val[key] is not a function
However, the following executes successfully:
const validateInput = data => {
let errors = {};
const test = "firstName";
const errors = {...errors, ...val[test](data[test])};
return errors;
};
When I log keys I get an array of strings and when I log typeof key I also get string, so I don't understand why it will not work within the map function.
Thanks in advance.

Thanks to Jonas above I was able to figure it out. I'm comparing two fields (password and password2) inside of one function. The following code works:
const validateInput = data => {
let errors = {};
const keys = Object.keys(val);
keys.map(key => {
let error;
if (data.hasOwnProperty(key)) {
switch (key) {
case "password":
error = val[key](data[key], data[`${key}2`]);
break;
default:
error = val[key](data[key]);
break;
}
errors = { ...errors, ...error };
}
});
return { errors, isValid: isEmpty(errors) };
};

Related

map is not a function in testcafe

I am not able to use a map function inside a client function.
export function availableAudioBitrates() {
const getOptionNames = ClientFunction(() => {
const select = document.querySelector('[data-testid=audioBitrate-setting]');
const options = select.querySelectorAll('option');
console.log(typeof options);
//const values = [];
const values = options.map((option) => option.TextContent);
//options.forEach((option) => values.push(option.textContent));
return values;
});
return getOptionNames();
}
I have "options.foreach" statement working, but with map function, it is throwing an error that options.map is not a function.
Check the value of options, its either undefined or not an array. .map() requires an array to run, anything else will cause that error
Because that is a HTMLCollection, not an array.
Use Array.form(select.querrySelectorAll('option')).
export function availableAudioBitrates() {
const getOptionNames = ClientFunction(() => {
const select = document.querySelector('[data-testid=audioBitrate-setting]');
const options = Array.from(select.querySelectorAll('option'));
console.log(typeof options);
//const values = [];
const values = options.map((option) => option.TextContent);
//options.forEach((option) => values.push(option.textContent));
return values;
});
return getOptionNames();
}

Jest testing, keeps return undefined?

I'm trying to test a function with jest, and I simply can figure out what's wrong? It keeps saying it expects to return the output, but got undefined. I have tested the function elsewhere where it seems to return the correct array.
I'm calling my my function and passing it an Object, it's then supposed to return an array. Then I'm calling .toEqual(output) which is an array.
//This is my function
const allAddresses = [
];
const updateAllAddresses = (obj) => {
const transferAmount = obj.transferAmount;
const to = obj.to;
const transferAddress = obj.address;
const newBalance = obj.newBalance;
const addressArr = [...allAddresses];
console.log("This addressArr", addressArr);
console.log("this is obj", obj);
//To set your account to the new balance after transfer and
//to check if the address you transfer to is your own account
addressArr.map((address) => {
if (address.account === transferAddress) {
console.log("This is inside the map !!!!");
address.balance = Number(newBalance);
}
if (address.account === to) {
console.log("2");
address.balance = Number(transferAmount) + Number(address.balance);
}
console.log("last part of the testing", addressArr);
return addressArr;
});
};
const obj = {
};
const output = [
];
//This is my test
describe("Update array", () => {
test("update the array with the new information", () => {
expect(updateAllAddresses(obj)).toEqual(output);
});
});
You cannot short circuit and return inside a map function. You should return the object after the map
Also, when you change address inside the map; It really does not change anything, since that address variable will be removed from memory on next iteration
There is a problem with your updateAllAddresses method.
You are not returning anything then the result of your function becomes undefined;
add return to where you are using .map method.
return addressArr.map((address) => {
if (address.account === transferAddress) {
console.log("This is inside the map !!!!");
address.balance = Number(newBalance);
}
if (address.account === to) {
console.log("2");
address.balance = Number(transferAmount) + Number(address.balance);
}
console.log("last part of the testing", addressArr);
return address;
});

I can't send data from my indexed database

I lose the reference of the "value" variable when it is no longer in the "onsuccess" context. I don't know how to make this function asymmetric.
getList(){
let transaction = this.db.transaction([this.db_name], "readwrite");
transaction.oncomplete= _ => {
console.log("Success")
}
transaction.onerror = _ => {
console.log("Error")
}
let value = []
let objectStore = transaction.objectStore(this.db_name)
objectStore.getAll().onsuccess = e => {
value = e.target.result;
};
console.log(value)
return value
}
When I console.log(value) I get an empty array.
If I wanted to take this data and put it directly in my HTML it would have worked and these are the only examples I managed to find on the internet

Why do i receive an error message in the console that getStoredQuests.push is not a function at Object.addQuestionOnLocalStorage

Why do I receive an error message in the console that getStoredQuests.push is not a function at Object.addQuestionOnLocalStorage
class Question{
constructor(id, questionText, options, correctAnswer) {
this.id = id;
this.questionText = questionText;
this.options = options;
this.correctAnswer = correctAnswer;
}
}
let questionLocalStorage = {
setQuestionCollection: (newQuestion) => {
localStorage.setItem('questionCollection', JSON.stringify(newQuestion));
},
getQuestionCollection: () => {
return JSON.parse(localStorage.getItem('questionCollection'));
},
removeQuestionCollection: () => {
localStorage.removeItem('questionCollection');
}
}
newQuestion = new Question(questionId, newQuestText.value, optionsArr, corrAnswer);
getStoredQuests = questionLocalStorage.getQuestionCollection();
getStoredQuests.push(newQuestion);
questionLocalStorage.setQuestionCollection(getStoredQuests);
The error is because getStoredQuests is not an array. You have probably not considered if there is no question in local storage initially, then localStorage.getItem('questionCollection') will return empty string or it might be case that you have some value with key questionCollection in local storage but is not in proper format to to be parsed as JSON array object.
For the first case solution is to check if localStorage.getItem('questionCollection') is empty then return empty array from getQuestionCollection and for the second case you to need to properly format the array '(serialize the array to be stored with JSON.stringify)'.
To let your problem understand properly, open up console see if there are red lines

Draft.js. How to get all entities data from the ContentState

From official docs I know about 2 methods: get entity by its key and get last created entity. In my case, I also need a method to access all entities from current ContentState.
Is there any method that could perform this? If not, is there a one that can provide all entities keys?
const getEntities = (editorState, entityType = null) => {
const content = editorState.getCurrentContent();
const entities = [];
content.getBlocksAsArray().forEach((block) => {
let selectedEntity = null;
block.findEntityRanges(
(character) => {
if (character.getEntity() !== null) {
const entity = content.getEntity(character.getEntity());
if (!entityType || (entityType && entity.getType() === entityType)) {
selectedEntity = {
entityKey: character.getEntity(),
blockKey: block.getKey(),
entity: content.getEntity(character.getEntity()),
};
return true;
}
}
return false;
},
(start, end) => {
entities.push({...selectedEntity, start, end});
});
});
return entities;
};
How I get the all entities keys:
const contentState = editorState.getCurrentContent()
const entityKeys = Object.keys(convertToRaw(contentState).entityMap)
result:
[0, 1]
then you can call the getEntity(key) method to get the responding entity.
this is how convertToRaw(contentState) looks:
Bao, You will find it inside key called 'blocks'.
convertToRaw(contentState).blocks.map(el=>el.text)
It will give you an array of raw text.
Unfortunatelly your suggested way using convertToRaw doesnt work because it reindexes all keys to ["0", .., "n"], but the real keys differ when you act with the editor. New ones > n will be added and unused will be omitted.
const rawState = convertToRaw(contentState)
const { entityMap } = rawState;
This entityMap will have list of all entities. But this is an expensive conversion. Because, it will convert whole thing to raw. A better way is loop through blocks and check for entity.
You'll have to look at every character:
const { editorState } = this.state; // assumes you store `editorState` on `state`
const contentState = editorState.getCurrentContent();
let entities = [];
contentState.getBlockMap().forEach(block => { // could also use .map() instead
block.findEntityRanges(character => {
const charEntity = character.getEntity();
if (charEntity) { // could be `null`
const contentEntity = contentState.getEntity(charEntity);
entities.push(contentEntity);
}
});
});
Then you could access it via:
entities.forEach((entity, i) => {
if (entity.get('type') === 'ANNOTATION') {
const data = entity.get('data');
// do something
}
})

Categories

Resources