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
Related
I am having a problem with sessionStorage; in particular, I want the id of the ads to be saved in the session where the user puts the like on that particular favorite article.
However, I note that the array of objects that is returned contains the ids starting with single quotes, as shown below:
['', '1', '7']
but I want '1' to be shown to me directly.
While if I go into the sessionStorage I notice that like is shown as:
,1,7
ie with the leading comma, but I want it to start with the number directly.
How can I fix this?
function likeAnnunci(){
let likeBtn = document.querySelectorAll('.like');
likeBtn.forEach(btn => {
btn.addEventListener('click', function(){
let id = btn.getAttribute('ann-id');
//sessionStorage.setItem('like', [])
let storage = sessionStorage.getItem('like').split(',');
//console.log(storage);
if(storage.includes(id)){
storage = storage.filter(id_a => id_a != id);
} else {
storage.push(id);
}
sessionStorage.setItem('like', storage)
console.log(sessionStorage.getItem('like').split(','));
btn.classList.toggle('fas');
btn.classList.toggle('far');
btn.classList.toggle('tx-main');
})
})
};
function setLike(id){
if(sessionStorage.getItem('like')){
let storage = sessionStorage.getItem('like').split(',');
if(storage.includes(id.toString())){
return `fas`
} else {
return `far`
}
} else {
sessionStorage.setItem('like', '');
return`far`;
}
}
The main issue you're having is that you're splitting on a , instead of using JSON.parse().
Also, you've got some other code issues and logical errors.
Solution:
function likeAnnunci() {
const likeBtn = document.querySelectorAll('.like');
likeBtn.forEach((btn) => {
btn.addEventListener('click', function () {
let id = btn.getAttribute('ann-id');
//sessionStorage.setItem('like', [])
let storage = JSON.parse(sessionStorage.getItem('like') || '[]');
//console.log(storage);
if (!storage.includes(id)) {
storage.push(id);
}
sessionStorage.setItem('like', JSON.stringify(storage));
console.log(JSON.parse(sessionStorage.getItem('like')));
btn.classList.toggle('fas');
btn.classList.toggle('far');
btn.classList.toggle('tx-main');
});
});
}
More modular and optimal solution:
const likeBtns = document.querySelectorAll('.like');
// If there is no previous array stored, initialize it as an empty array
const initLikesStore = () => {
if (!sessionStorage.getItem('likes')) sessionStorage.setItem('likes', JSON.stringify([]));
};
// Get the item from sessionStorage and parse it into an array
const grabLikesStore = () => JSON.parse(sessionStorage.getItem('likes'));
// Set a new value for the likesStore, automatically serializing the value into a string
const setLikesStore = (array) => sessionStorage.setItem('likes', JSON.stringify(array));
// Pass in a value.
const addToLikesStore = (value) => {
// Grab the current likes state
const pulled = grabStorage();
// If the value is already there, do nothing
if (pulled.includes(value)) return;
// Otherwise, add the value and set the new array
// of the likesStore
storage.push(value);
setLikesStore(pulled);
};
const likeAnnunci = (e) => {
// Grab the ID from the button clicked
const id = e.target.getAttribute('ann-id');
// Pass the ID to be handled by the logic in the
// function above.
addToLikesStore(id);
console.log(grabLikesStore());
btn.classList.toggle('fas');
btn.classList.toggle('far');
btn.classList.toggle('tx-main');
};
// When the dom content loads, initialize the likesStore and
// add all the button event listeners
window.addEventListener('DOMContentLoaded', () => {
initLikesStore();
likeBtns.forEach((btn) => btn.addEventListener('click', likeAnnunci));
});
Coming across something i thought would have worked, but does not.
I have the following function that takes an input and needs to update one value in the mongodb.
const updateSkillXP = (data) =>{
//data = { username:username, sk:sk, xp:100 }
const collection = db.collection('player');
let q = {username:data.username}
//craft a key depending on what skill code comes through.
let s = "skills."+data.sk;
u = {$set: {s : data.xp}}
return collection.updateOne(q,u,(err,res) =>{
if(err) console.log(err);
})
}
The MongoDB document looks as follows
player = {
x:0,
y:0,
username:"foo",
skills : { //I need one of the following to update.
atk:0,
str:0,
def:0,
hp:0
}
}
When I executed the above, it added 'S' Property, but i was expecting to change the value of say 'atk' to what ever xp came through?
Answer:
JavaScript set object key by variable
const updateSkillXP = (data) =>{
//data = { username:username, sk:sk, xp:100 }
const collection = db.collection('player');
let q = {username:data.username}
let s = "skills."+data.sk;
let obj = {};
obj[s] = data.xp;
u = {$set: obj}
return collection.updateOne(q,u,(err,res) =>{
if(err) console.log(err);
})
}
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
I have written the below code
updatePublication(projectName, publicationId, publicationObj, callback) {
let self = this;
this.initDatabase(function (db) {
let tx = self.db.transaction(self.PUBLICATIONS, self.READ_WRITE);
let store = tx.objectStore(self.PUBLICATIONS);
let index = store.index(self.PROJECT_NAME);
let request3 = index.openCursor(IDBKeyRange.only(projectName));
console.log("hrere");
request3.onsuccess = function () {
let cursor = request3.result;
if (cursor) {
let updateObject = cursor.value;
if (updateObject.publicationID == publicationId) {
updateObject.publicationObject = publicationObj;
cursor.update(updateObject);
callback(publicationId);
}
cursor.continue();
} else {
callback(publicationId);
}
};
});
}
But this give error:
I checked the cause of error. It is beacuse , publicationObj which is passed has an object named _requestObjectBuilder which is of the type Subscriber.
used somewhere in the code like this:
_requestObjectBuilder = interval(1000).pipe(tap(() => {}));
Is there any way i can modify my updatePublication code to ignore this value?
Does indexed db support a query for ignoring a value and saving the data?
Note: If i set publicationObj._requestObjectBuilder = undefined, the data gets saved to indexedDB. But this breaks the functionality where _requestObjectBuilder is used.
Fixed the issue by cloning the object and setting it to undefined
let clonedObject = Object.assign({}, publicationObject);
clonedObject._requestObjectBuilder = undefined;
Now i am updating the clonedObject
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
}
})