I want the return to be in my parent function, for example:
const blockLetters = lastD => {
if(lastD != undefined && isNaN(Number.parseInt(lastD))){
return;
}
}
const handleCVC = e => {
e.preventDefault();
let newcvc = e.target.value;
let newcvcArr = newcvc.split("");
let newLength = (e.target.value).length;
let lastNewDigit = newcvcArr[newLength-1]
blockLetters(lastNewDigit);
setcvc(newcvc)
}
The purpose is that the returns; of the blockLetters affect directly the handleCVC function and it dont excecute his last line, but actually this returns; only affects the blockLetters function.
You could take a function which returns a true/truthy for not having a valid value for checking and returning in a calling function.
Actually it boils down to isNaN which could be used instead of having a dedicated function.
const isNoNumber = lastD => isNaN(Number.parseInt(lastD, 10));
const handleCVC = e => {
e.preventDefault();
let newcvc = e.target.value;
let newcvcArr = newcvc.split("");
let newLength = (e.target.value).length;
let lastNewDigit = newcvcArr[newLength-1];
if (isNoNumber(lastNewDigit)) return;
setcvc(newcvc);
}
I'm trying to create a chrome extension, but I am having some trouble updating my DB.
In the code below I am using index.get to the the object that contains a certain value. If such an object doesn't exist I will create a new one, which works just fine.
But if the DB contains an object with the specified value, I want to append a new object to an array (allMessages) that is inside the object I searched for. The details doesn't really matter in this case.
What is important is to find out if the way I'm adding this new obj to the array (allMessages) is a valid way of updating the database.
records.forEach((person) => {
console.log("here1");
const index = objectStore.index("urlKeyValue");
let search = index.get(person.urlKeyValue);
search.onsuccess = function (event) {
if (search.result === undefined) {
// no record with that key
let request = objectStore.add(person);
request.onsuccess = function () {
console.log("Added: ", person);
};
} else {
// here I'm iterating an array that is inside the obj I searched for,
// and then checking if the key for that array matches **theUserId**
for (userObj of event.target.result.allMessages) {
if (theUserId == Object.keys(userObj)) {
// is this part correct. Is it possible to update the DB this way?
let objToAdd1 = {
time: person.allMessages[0][theUserId][0].time,
msg: person.allMessages[0][theUserId][0].msg,
};
let currentObj = userObj[theUserId];
let updatedObj = currentObj.push(objToAdd1);
}
}
)}
Using objectStore.openCursor you can update only part of the record.
The following updates only book prices.
const transaction = db.transaction("books", "readwrite");
const objectStore = transaction.objectStore("books");
records = [{ id: "kimetu", price: 600 }];
records.forEach((book) => {
const index = objectStore.index("id");
const search = index.get(book.id);
search.onsuccess = () => {
if (search.result === undefined) {
const request = objectStore.add(book);
request.onsuccess = () => {
console.log("Added: ", book);
};
} else {
const request = objectStore.openCursor(IDBKeyRange.only(book.id));
request.onsuccess = () => {
const cursor = request.result;
if (cursor) {
cursor.value.price = 1000;
const updateRequest = cursor.update(cursor.value);
updateRequest.onsuccess = () => {
console.log("Updated: ", cursor.value.price);
};
cursor.continue();
}
};
}
}
});
I came up with this question on Stack Overflow because I could not solve a small problem that I had been dealing with for a long time.
One problem I do not understand is:
I want a function that automatically sets the data from the API and automatically saves it directly to Local Storage or Database by specific local time zone using with pure javascript.
I want the data to be automatically saved to LocalStorage or Database at 12:01 local time and 4:30 pm then display it to HTML DOM.
I want a API get the update data in every seconds.
Please take a look at some of the codes I wrote myself.
/* ---------------------------------------------------------------------- */
/* -------------------------- Retrieve API ------------------------- */
/* ---------------------------------------------------------------------- */
// Fetch Meow Data Main();
const pjk_Meow = async () => {
const base = 'aHR0cHM6Ly90d29';
const cors = atob('aHR0cHM6Ly9jb3JzLmNo');
const pjk_meow = atob(base);
try {
const res = await fetch(cors + pjk_meow);
const data = await res.json();
return data;
} catch (error) {
return error.message;
}
};
/* ---------------------------------------------------------------------- */
/* -------------------------- Schedule and Save to Local Storage ------------------------- */
/* ---------------------------------------------------------------------- */
// // 12:00 PM Request Data
const pjk_Meow_4 = async () => {
const base = 'aHR0cHM6Ly90d29';
const cors = atob('aHR0cHM6Ly9jb3JzLmNoY');
const pjk_meow = atob(base);
// Set default time what I want it to.
let d_time = '12:03:12 PM';
let d_time_2 = '12:10:12 PM';
let current_time = new Date().toLocaleTimeString();
try {
if (current_time === d_time || current_time <= 13) {
try {
const res = await fetch(cors + pjk_meow);
const data = await res.json();
// Working with LS
let data_serialized = JSON.stringify(data);
localStorage.setItem('afternoon', data_serialized);
return data_serialized;
} catch (error) {
return false;
}
}
} catch (error) {
return false;
}
};
pjk_Meow_4();
// 12:00 PM Callback and output to html
const twelve_pm = () => {
setInterval(() => {
try {
let third_Data = JSON.parse(localStorage.getItem('afternoon'));
const setThird = document.getElementById('setThird');
const valueThird = document.getElementById('valueThird');
const resultThird = document.getElementById('resultThird');
// If there is no any data in LS, this condition will run
if (localStorage.length <= 0 || localStorage === undefined) {
setThird.innerText = '------';
valueThird.innerText = '-------';
resultThird.innerText = '--';
}
// Destructuring 12:00 PM Result
const { set, val, result } = third_Data;
// Check time and get data
setThird.innerText = set;
valueThird.innerText = val;
resultThird.innerText = result;
} catch (error) {
return false;
}
}, 3000);
};
twelve_pm();
// // 4:30 PM Request Data
const pjk_Meow_3 = async () => {
const base = 'aHR0cHM6Ly90d29kLml0';
const cors = atob('aHR0cHM6Ly9jb3J');
const pjk_meow = atob(base);
// Set default time what I want it to.
let d_time_1 = '04:35:00 PM';
let d_time_2 = '16:35:00 PM';
let current_time = new Date().toLocaleTimeString();
// let current_time = new Date().getHours();
try {
if (current_time === d_time_1 || current_time >= d_time_2) {
try {
const res = await fetch(cors + pjk_meow);
const data = await res.json();
// Working with LS
let data_serialized = JSON.stringify(data);
localStorage.setItem('evening', data_serialized);
return data_serialized;
} catch (error) {
console.log(error.message);
}
}
} catch (error) {
return false;
}
};
pjk_Meow_3();
// 4:30 PM Callback and output to html
const four_pm = () => {
setInterval(() => {
try {
let second_Data = JSON.parse(localStorage.getItem('evening'));
const setSec = document.getElementById('setSec');
const valueSec = document.getElementById('valueSec');
const resultSec = document.getElementById('resultSec');
// If there is no any data in LS, this condition will run
if (localStorage.length <= 0 || localStorage === undefined) {
setSec.innerText = '------';
valueSec.innerText = '-------';
resultSec.innerText = '--';
}
// Destructuring 12:00 PM Result
const { set, val, result } = second_Data;
// Check time and get data
setSec.innerText = set;
valueSec.innerText = val;
resultSec.innerText = result;
} catch (error) {
return false;
}
}, 3000);
};
four_pm();
OR
Please take a look at some of the codes I wrote updated.
// Set the default time what I want to save to the localStorage
let d = new Date();
let h = d.getHours();
let m = d.getMinutes();
let compile = `${h}:${m}`;
try {
if (compile === '4:30' || compile >= '16:30') {
try {
const res = await fetch(cors + pjk_meow);
const data = await res.json();
// Working with LS
let data_serialized = JSON.stringify(data);
localStorage.setItem('evening', data_serialized);
return data_serialized;
} catch (error) {
console.log(error.message);
}
}
} catch (error) {
return false;
}
I get an “infinite update loop in a component render function” and it seems to be triggered by a vuex getter but I have seriously no idea why. Any hint would help me a lot
getPlanningsForPlanner: (state, getters, rootState, rootGetters) => () => {
let people = getters['getPeopleOrderedBy']();
return rootState.plannings.map((planning) => {
if (planning.adhoc_text === null) {
planning.epic = rootGetters['moduleJIRA/getEpicByKey'](planning.epic_key);
if (typeof (planning.epic) !== 'undefined')
planning.project = rootGetters['moduleJIRA/getProjectByKey'](planning.epic.fields.project.key)
} else {
planning.epic = {};
planning.project = {};
}
// parse dates
planning.startDate = moment(planning.start_date);
planning.endDate = moment(planning.end_date);
// add people
planning.people = people.find(elm => elm.id === planning.people_id);
// calculation of hours
planning.dailyHours = getters['daysToHours'](1, planning.load);
planning.businessDays = planning.startDate.businessDiff(planning.endDate) + 1;
planning.plannedHours = getters['daysToHours'](planning.businessDays, planning.load);
if (!planning.pinned_end) {
let fixPlannedEpics = rootState.plannings.filter(_planning => _planning.epic_key === planning.epic_key && _planning.pinned_end);
let fixPlannedHours = fixPlannedEpics.reduce((sum, _planning) => sum + _planning.plannedHours, 0);
let openlyPlannedEpics = rootState.plannings.filter(_planning => _planning.epic_key === planning.epic_key && !_planning.pinned_end);
let hours = Math.max((planning.epic.budget - planning.epic.sumTimeSpent - fixPlannedHours) / openlyPlannedEpics.length, planning.dailyHours);
planning.endDate = moment(planning.startDate).businessAdd(Math.round(hours / planning.dailyHours));
}
// add indices in timeBeam
let indices = getters['getIndices'](planning.startDate, planning.endDate);
planning.startIndex = indices.start;
planning.endIndex = indices.end;
return planning
});
},
How to limit max characters in draft js?
I can get length of the state like that, but how to stop updating component?
var length = editorState.getCurrentContent().getPlainText('').length;
You should define handleBeforeInput and handlePastedText props. In handler-functions, you check the length of current content + length of pasted text and if it reaches the maximum you should return 'handled' string.
UPD 21.03.2018: Upgraded to the last versions of react/react-dom (16.2.0) and Draft.js (0.10.5).
Working example - https://jsfiddle.net/Ln1hads9/11/
const {Editor, EditorState} = Draft;
const MAX_LENGTH = 10;
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty()
};
}
render() {
return (
<div className="container-root">
<Editor
placeholder="Type away :)"
editorState={this.state.editorState}
handleBeforeInput={this._handleBeforeInput}
handlePastedText={this._handlePastedText}
onChange={this._handleChange}
/>
</div>
);
}
_getLengthOfSelectedText = () => {
const currentSelection = this.state.editorState.getSelection();
const isCollapsed = currentSelection.isCollapsed();
let length = 0;
if (!isCollapsed) {
const currentContent = this.state.editorState.getCurrentContent();
const startKey = currentSelection.getStartKey();
const endKey = currentSelection.getEndKey();
const startBlock = currentContent.getBlockForKey(startKey);
const isStartAndEndBlockAreTheSame = startKey === endKey;
const startBlockTextLength = startBlock.getLength();
const startSelectedTextLength = startBlockTextLength - currentSelection.getStartOffset();
const endSelectedTextLength = currentSelection.getEndOffset();
const keyAfterEnd = currentContent.getKeyAfter(endKey);
console.log(currentSelection)
if (isStartAndEndBlockAreTheSame) {
length += currentSelection.getEndOffset() - currentSelection.getStartOffset();
} else {
let currentKey = startKey;
while (currentKey && currentKey !== keyAfterEnd) {
if (currentKey === startKey) {
length += startSelectedTextLength + 1;
} else if (currentKey === endKey) {
length += endSelectedTextLength;
} else {
length += currentContent.getBlockForKey(currentKey).getLength() + 1;
}
currentKey = currentContent.getKeyAfter(currentKey);
};
}
}
return length;
}
_handleBeforeInput = () => {
const currentContent = this.state.editorState.getCurrentContent();
const currentContentLength = currentContent.getPlainText('').length;
const selectedTextLength = this._getLengthOfSelectedText();
if (currentContentLength - selectedTextLength > MAX_LENGTH - 1) {
console.log('you can type max ten characters');
return 'handled';
}
}
_handlePastedText = (pastedText) => {
const currentContent = this.state.editorState.getCurrentContent();
const currentContentLength = currentContent.getPlainText('').length;
const selectedTextLength = this._getLengthOfSelectedText();
if (currentContentLength + pastedText.length - selectedTextLength > MAX_LENGTH) {
console.log('you can type max ten characters');
return 'handled';
}
}
_handleChange = (editorState) => {
this.setState({ editorState });
}
}
ReactDOM.render(<Container />, document.getElementById('react-root'))
Mikhail's methods are correct, but the handler return value is not. 'not_handled' is a fall-through case that allows the Editor component to process the input normally. In this case, we want to stop the Editor from processing input.
In older versions of DraftJS, it looks like the presence of a string evaluated to 'true' in the handling code, and so the above code behaved correctly. In later versions of DraftJS, the above fiddle doesn't work - I don't have the reputation to post more that one Fiddle here, but try Mikhail's code with v0.10 of DraftJS to replicate.
To correct this, return 'handled' or true when you don't want the Editor to continue handling the input.
Fiddle with corrected return values
For example,
_handleBeforeInput = () => {
const currentContent = this.state.editorState.getCurrentContent();
const currentContentLength = currentContent.getPlainText('').length
if (currentContentLength > MAX_LENGTH - 1) {
console.log('you can type max ten characters');
return 'handled';
}
}
See the DraftJS docs on Cancelable Handlers for more.
This is a bit of an old thread, but thought I would share a solution for anyone else facing the problem of character limit and behaviour while pasting text...
Put together something pretty quickly based on the above code by Mikhail to handle this use case which works for me - although I haven't done any work on trying to optimise it.
Basically the handle pasted text looks like so:
const __handlePastedText = (pastedText: any) => {
const currentContent = editorState.getCurrentContent();
const currentContentLength = currentContent.getPlainText('').length;
const selectedTextLength = _getLengthOfSelectedText();
if (currentContentLength + pastedText.length - selectedTextLength > MAX_LENGTH) {
const selection = editorState.getSelection()
const isCollapsed = selection.isCollapsed()
const tempEditorState = !isCollapsed ? _removeSelection() : editorState
_addPastedContent(pastedText, tempEditorState)
return 'handled';
}
return 'not-handled'
}
We have a helper function to handle the deletion of the selection prior to pasting new characters which returns the new editor state:
const _removeSelection = () => {
const selection = editorState.getSelection()
const startKey = selection.getStartKey()
const startOffset = selection.getStartOffset()
const endKey = selection.getEndKey()
const endOffset = selection.getEndOffset()
if (startKey !== endKey || startOffset !== endOffset) {
const newContent = Modifier.removeRange(editorState.getCurrentContent(), selection, 'forward')
const tempEditorState = EditorState.push(
editorState,
newContent,
"remove-range"
)
setEditorState(
tempEditorState
)
return tempEditorState
}
return editorState
}
and finally the function to add the pasted text with a limit:
const _addPastedContent = (input: any, editorState: EditorState) => {
const inputLength = editorState
.getCurrentContent()
.getPlainText().length;
let remainingLength = MAX_LENGTH - inputLength;
const newContent = Modifier.insertText(
editorState.getCurrentContent(),
editorState.getSelection(),
input.slice(0,remainingLength)
);
setEditorState(
EditorState.push(
editorState,
newContent,
"insert-characters"
)
)
}
Link to worked example:
https://codesandbox.io/s/objective-bush-1h9x6
As Mikhail mentioned, you need to handle typing and pasting text. Here are both handlers. Note the paste handler will preserve text that is not outside the limit
function handleBeforeInput(text: string, state: EditorState): DraftHandleValue {
const totalLength = state.getCurrentContent().getPlainText().length + text.length;
return totalLength > MAX_LENGTH ? 'handled' : 'not-handled';
}
function handlePastedText(text: string, _: string, state: EditorState): DraftHandleValue {
const overflowChars = text.length + state.getCurrentContent().getPlainText().length - MAX_LENGTH;
if (overflowChars > 0) {
if (text.length - overflowChars > 0) {
const newContent = Modifier.insertText(
state.getCurrentContent(),
state.getSelection(),
text.substring(0, text.length - overflowChars)
);
setEditorState(EditorState.push(state, newContent, 'insert-characters'));
}
return 'handled';
} else {
return 'not-handled';
}
}
Let's think about this for a second. What is called to make the changes? Your onChange, right? Good. We also know the length. Correct? We attact the "worker" which is the onChange:
const length = editorState.getCurrentContent().getPlainText('').length;
// Your onChange function:
onChange(editorState) {
const MAX_LENGTH = 10;
const length = editorState.getCurrentContent().getPlainText('').length;
if (length <= MAX_LENGTH) {
this.setState({ editorState }) // or this.setState({ editorState: editorState })
}
} else {
console.log(`Sorry, you've exceeded your limit of ${MAX_LENGTH}`)
}
I have not tried this but my 6th sense says it works just fine.