vuex getter triggers 'infinite update loop in a component render function' - javascript

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
});
},

Related

Use multiple SpeechRecognition() constructors to listen in multiple languages at the same time

I've setup a test script that successfully transcribes what I am saying, both in english and german if I set the lang property beforehand.
However, I want it to automatically recognize which language I am speaking. Since SpeechRecognition does not support this, my idea was to just use multiple constructors at the same time, each with their own lang property and then just use the transcription with the highest confidence score.
However, this does not seem to work, as chrome does not transcribe anything if i start both constructors at once. In fact, I have to close chrome alltogether before it will start working again.
Any ideas? Here is the full code, if I uncomment the commented lines it will not work.
function listenEN(){
navigator.webkitGetUserMedia(
{ audio: true },
() => {},
() => {},
)
let triggerPhrase = "Computer"
triggerPhrase = triggerPhrase ? triggerPhrase.toLowerCase() : "Alexa"
let voices = window.speechSynthesis.getVoices()
const voiceEN = voices.find((voice) => voice.name === 'Google US English')
const voiceDE = voices.find((voice) => voice.name === 'Google DE German')
async function notifyStartListening() {
const utterance = new SpeechSynthesisUtterance("beep!");
utterance.rate = 2;
utterance.pitch = 1.5;
utterance.voice = voiceEN;
speechSynthesis.speak(utterance);
}
const recognitionEN = new webkitSpeechRecognition()
recognitionEN.lang = 'en-US'
recognitionEN.continuous = true
const recognitionDE = new webkitSpeechRecognition()
recognitionDE.lang = 'de-DE'
recognitionDE.continuous = true
try {
let isActive = false
function startListening() {
notifyStartListening();
isActive = true
}
recognitionEN.addEventListener('result', async () => {
recognitionEN.lang = 'en-US'
const transcriptEN = event.results[event.results?.length - 1][0].transcript
console.log(transcriptEN)
if (isActive) {
let instruction = transcriptEN
if (transcriptEN.trimStart().startsWith(triggerPhrase)) {
instruction = transcriptEN.trimStart().substring(triggerPhrase.length)
}
isActive = false
return
}
const trimmed = transcriptEN.trimStart().trimEnd().toLowerCase()
if (trimmed.startsWith(triggerPhrase)) {
const instructionEN = trimmed.substring(triggerPhrase.length)
if (instructionEN && instructionEN?.length > 2) {
let confidenceEN = document.createElement('p')
confidenceEN.innerHTML = event.results[event.results?.length - 1][0].confidence
document.body.appendChild(confidenceEN);
} else {
startListening()
}
}
})
recognitionDE.addEventListener('result', async () => {
recognitionDE.lang = 'de-DE'
const transcriptDE = event.results[event.results?.length - 1][0].transcript
console.log(transcriptDE)
if (isActive) {
let instruction = transcriptDE
if (transcriptDE.trimStart().startsWith(triggerPhrase)) {
instruction = transcriptDE.trimStart().substring(triggerPhrase.length)
}
isActive = false
return
}
const trimmed = transcriptDE.trimStart().trimEnd().toLowerCase()
if (trimmed.startsWith(triggerPhrase)) {
const instructionDE = trimmed.substring(triggerPhrase.length)
if (instructionDE && instructionDE?.length > 2) {
let confidenceDE = document.createElement('p')
confidenceDE.innerHTML = event.results[event.results?.length - 1][0].confidence
document.body.appendChild(confidenceDE);
} else {
startListening()
}
}
})
recognitionEN.addEventListener('error', (event) => {
console.log(event)
})
recognitionEN.onend = function () {
recognitionEN.start()
}
recognitionEN.start()
/*recognitionDE.addEventListener('error', (event) => {
console.log(event)
})
recognitionDE.onend = function () {
recognitionDE.start()
}
recognitionDE.start() */
} catch (e) {
console.error(e)
}
}

Discord anti nuke bot whitelist check error

i get error
let executor = await this.members.fetch(executorID);
^^^^^
SyntaxError: await is only valid in async function
when using the code below (use is to check if user breaks any of set filters and if so remove roles or ban user whatever they set option to)
ive tried my best to lable what parts of code does please not english isnt my first language
ive only recieved this error since trying to add a check whitelist feature - everything else works without the whitelist check code
without the code for whitelist the code works and performs as intended and the whitelist code succesfully logs ids for that guild
if(whitelisted && whitelisted.length) {
whitelisted.forEach(x => {
if (executorID === x.user) return;
const { Structures } = require('discord.js');
let whitelisted = db.get(`whitelist_${message.guild.id}`)
const { limits, defaultPrefix } = require('../config.js');
Structures.extend('Guild', Guild => {
class GuildExt extends Guild {
constructor(...args) {
super(...args);
}
get prefix() {
return this.get('prefix', defaultPrefix);
}
get(key, fallback) {
return this.client.db.get(`${this.id}_${key}`) || fallback;
}
set(key, data) {
return this.client.db.set(`${this.id}_${key}`, data);
}
delete(key) {
return this.client.db.delete(`${this.id}_${key}`);
}
resolveChannel(channelID) {
const channel = this.channels.cache.get(channelID);
return channel;
}
get limits() {
var obj = {};
for (var k in limits) {
obj[k] = {
minute: this.get(
`limits.${k}.minute`,
limits[k].per_minute
),
hour: this.get(`limits.${k}.hour`, limits[k].per_hour)
};
}
return obj;
}
getActions(limit = 10, filter = () => true) {
var obj = {};
var l = limits;
for (var k in limits) {
obj[k] = {
name: this.client.Utils.toProperCase(k),
actions: this.client.Utils.convertEntries(
[
...this.get(
this.client.Utils.convertLimitNameToActionType(
k
),
[]
),
...this.get(
`archive.${this.client.Utils.convertLimitNameToActionType(
k
)}`,
[]
)
]
.filter(filter)
.slice(0, limit)
)
};
}
return obj;
}
find_entry(action, filter) {
let guild = this;
return new Promise(resolve => {
(async function search(iter) {
//console.log(`ACTION = ${action} | ITER = ${iter}`);
if (!guild.me) return resolve(null);
if (guild.me.hasPermission('VIEW_AUDIT_LOG')) {
let logs = await guild.fetchAuditLogs({
limit: 10,
type: action
});
let entries = logs.entries;
let entry = null;
entries = entries.filter(filter);
for (var e of entries)
if (!entry || e[0] > entry.id) entry = e[1];
if (entry) return resolve(entry);
}
if (++iter === 5) return resolve(null);
else return setTimeout(search, 200, iter);
})(0);
});
}
push_entry(entry, displayName) {
const action = ['MEMBER_KICK', 'MEMBER_BAN_ADD'].includes(
entry.action
)
? 'MEMBER_REMOVE'
: entry.action;
const oneHourAgo = Date.now() - 1000 * 60 * 60;
// Fetch Entries for a sepcific action (Last Hour)
let entries = this.get(action, []);
// Filter entries older than one hour to a new variable
let olderThanOneHour = entries.filter(
i => !(i.timestamp > oneHourAgo)
);
// Prepend entries older than one hour to the archive
if (olderThanOneHour.length > 0)
this.set(`archive.${action}`, [
...olderThanOneHour,
...this.get(`archive.${action}`, [])
]);
// Filter entries older than one hour from old variable
entries = entries.filter(i => i.timestamp > oneHourAgo);
// Prepend new entry if not already found
if (
!entries.find(
i =>
i.target.id === entry.target.id &&
i.executor.id === entry.executor.id
)
)
entries.unshift({
timestamp: entry.createdTimestamp,
action: entry.action,
target: {
id: entry.target.id,
displayName,
targetType: entry.targetType
},
executor: {
id: entry.executor.id,
displayName: entry.executor.tag
}
});
// Update entries newer than one hour
return this.set(action, entries);
}
async check_limits(entries, executorID, configAction) {
// Ignore if executor is the owner or is whitelisted
if (executorID === this.ownerID) return;
if(whitelisted && whitelisted.length) {
whitelisted.forEach(x => {
if (executorID === x.user) retrun;
// Filter actions relating to executor
const oneMinuteAgo = Date.now() - 1000 * 60;
let executorActionsHour = entries.filter(
i => i.executor.id === executorID
);
let executorActionsMinute = executorActionsHour.filter(
i => i.timestamp > oneMinuteAgo
);
console.log(
`${configAction}/${executorID}: LAST_HOUR: ${executorActionsHour.length} LAST_MINUTE: ${executorActionsMinute.length} `
);
let limits = this.limits;
let limitReached = null;
if (executorActionsHour.length >= limits[configAction].hour)
limitReached = 'Hour';
if (executorActionsMinute.length >= limits[configAction].minute)
limitReached = 'Minute';
// Check if the amount of actions is greater than or equal to the limit
if (limitReached) {
// Remove all of the executor's roles
let executor = await this.members.fetch(executorID);
executor.roles.remove(executor.roles.cache);
// Handle managed roles
let managed = executor.roles.cache
.filter(r => r.managed)
.array();
for (var i = 0; i < managed.length; i++)
managed[i].setPermissions(0, 'Guardian Action');
// Notify owner, executor, and logging channel
const embed = this.client.util
.embed()
.setTitle(`Limit Reached - ${limitReached}`)
.setDescription(
this.client.Utils.convertEntries(
limitReached === 'Hour'
? executorActionsHour
: executorActionsMinute
)
)
.setColor(0x7289da);
await this.owner.send(
embed.setFooter(
"This message was sent to you because you're the Guild owner."
)
);
await executor.send(
embed.setFooter(
'This message was sent to you because you were the executor.'
)
);
const loggingChannel = this.resolveChannel(
this.get(`loggingChannelID`)
);
if (loggingChannel)
await loggingChannel.send(embed.setFooter(''));
}
})
}
}
}
return GuildExt;
});
i am new to JS and any help would be appreciated
please dont hate if i do have bad syntax !!
i am new - sorry if i dont get things the first time
You forgot to make your forEach function async, just change it to:
/* ... */
whitelisted.forEach(async (x) => {
/* ... */
let executor = await this.members.fetch(executorID);
/* ... */
}
/* ... */
Not part of your question but you misspelled return here
if (executorID === x.user) retrun;
Your line
let executor = await this.members.fetch(executorID);
is inside a non-async anonymous function in:
if (whitelisted && whitelisted.length) {
whitelisted.forEach(x => { // <- This line
if (executorID === x.user) return;
// ...
Try changing it with:
if (whitelisted && whitelisted.length) {
whitelisted.forEach(async (x) => { // <- Use async here
if (executorID === x.user) return;
// ...
Also, avoid using forEach to make asynchronous calls.

How to get item from JSON and use if/else to state what should follow?

Is it possible to get the AGE from the regular results[0].AGE? I cant seem to find a way to get the value in the first place. Also, is it possible to have an if statement that does .then(vs => document.getElementById('GBPM').innerHTML = vs.toFixed(2)) when the age is under 10 and to do .then(vs => document.getElementById('GBPM').innerHTML = "-Offline-" when the age is over 10?
I have tired to use regular if else, but nothing is working. I also tired to get the AGE value, but no success.
const getData5 = () =>
fetch('https://www.purpleair.com/json?show=13183')
.then(serverResponse => serverResponse.json())
.then(apiResultObject => apiResultObject.results[0])
.then(result => JSON.parse(result.Stats))
.then(stat => stat.v)
getData5()
.then((response) => {
console.log(response)
if(response.AGE <= 10){
let vs = response.Stats.v;
document.getElementById('RBPM').innerHTML = vs.toFixed(2);
document.getElementById('RBAQI').innerHTML = aqiFromPM(vs,'RBAQI','RBPM',"RBLVL")
}else if(response.AGE >= 10){
document.getElementById('RBPM').innerHTML = "-Offline-";
document.getElementById('RBPM').style.backgroundColor = "#808080";
document.getElementById('RBAQI').innerHTML = "-Offline-";
document.getElementById('RBAQI').style.backgroundColor = "#808080";
document.getElementById('RBLVL').innerHTML = "-Offline-";
document.getElementById('RBLVL').style.backgroundColor = "#808080";
}
});
The return value is 1 using the link in the fetch attribute.
NEW ERROR CODE:
const getData6 = () =>
fetch('https://www.purpleair.com/json?show=13183')
.then(serverResponse => serverResponse.json())
.then(arr => {
const wanted = arr.results[0]
wanted.Stats = JSON.parse(wanted.Stats);
return wanted
})
getData6()
.then(item =>{
console.log(`Age ${item.AGE}`);
console.log(`Stats.v ${item.Stats.v}`)
console.log(`PM2_5Value ${item.PM2_5Value}`)
})
.then((response) => {
if(item.AGE <= 10){
let vs = item.PM2_5Value;
document.getElementById('RBPM').innerHTML = vs.toFixed(2);
document.getElementById('RBAQI').innerHTML = aqiFromPM(vs,'RBAQI','RBPM',"RBLVL")
}else if(item.AGE >= 10){
document.getElementById('RBPM').innerHTML = "-Offline-";
document.getElementById('RBPM').style.backgroundColor = "#808080";
document.getElementById('RBAQI').innerHTML = "-Offline-";
document.getElementById('RBAQI').style.backgroundColor = "#808080";
document.getElementById('RBLVL').innerHTML = "-Offline-";
document.getElementById('RBLVL').style.backgroundColor = "#808080";
}
});
The AGE property of each object is a sibling of Stats, not a child.
So you need to return the whole results[0] object
const getData4 = () =>
fetch('https://www.purpleair.com/json?show=22269')
.then(serverResponse => serverResponse.json())
.then(arr => {
const wanted = arr.results[0]
wanted.Stats = JSON.parse(wanted.Stats);
return wanted
})
getData4().then(item =>{
console.log(`Age ${item.AGE}`);
console.log(`Stats.v ${item.Stats.v}`)
console.log(`PM2_5Value ${item.PM2_5Value}`)
})
checkout how Promise (and async in general) works. then is beeing invoked only once (and it's consumed)
const getData4 = () =>
fetch('https://www.purpleair.com/json?show=22269')
.then(serverResponse => {
var json = serverResponse.json();
if (json.yourAgeField > 10){ ...set GBPM }
else { ..set -Offline- }
})
You need to return the Promise from the fetch, after that you can use then on getData4()
Try the following code.Hope it helps.Forgot to change age to AGE
const getData5 = () => {
return fetch('https://www.purpleair.com/json?show=22269')
.then(serverResponse => serverResponse.json())
.then(apiResultObject => apiResultObject.results[0])
}
getData5()
.then((item) => {
console.log(item)
if(item.AGE <= 10){
let vs = item.Stats.v;
document.getElementById('RBPM').innerHTML = vs.toFixed(2);
document.getElementById('RBAQI').innerHTML = aqiFromPM(vs,'RBAQI','RBPM',"RBLVL")
}else if(item.AGE >= 10){
document.getElementById('RBPM').innerHTML = "-Offline-";
document.getElementById('RBPM').style.backgroundColor = "#808080";
document.getElementById('RBAQI').innerHTML = "-Offline-";
document.getElementById('RBAQI').style.backgroundColor = "#808080";
document.getElementById('RBLVL').innerHTML = "-Offline-";
document.getElementById('RBLVL').style.backgroundColor = "#808080";
}
});

How to Implement Method Chaining

Is there a way to chain the following methods from Cache class
cache = cache.getKey(key) || cache.setKey(key).get(key);
// cache = cache.getKey(key) || cache.setKey(key).getKey(key);
I know we have native methods Map.prototype​.set() and Map.prototype​.get() but I want to implement it this way. Let me know if you have any suggestions.
function isObject(arg) {
const typeOfObj = typeof arg;
return (typeOfObj === 'object' || typeOfObj === 'function') && arg !== null;
}
class Cache {
constructor() {
this.map = new Map();
this.weakmap = new WeakMap();
}
setKey(key) {
const map = this[isObject(key) ? 'weakmap' : 'map'];
return map.set(key, new Cache());
}
getKey(key) {
const map = this[isObject(key) ? 'weakmap' : 'map'];
return map.get(key);
}
}
function getCache(args, cache) {
for (const key of args) {
cache = cache.getKey(key) || cache.setKey(key).get(key);
// cache = cache.getKey(key) || cache.setKey(key).getKey(key);
}
return cache;
}
function memoize(fn) {
const cache = new Cache();
return (...args) => {
const item = getCache(args, cache);
if (Reflect.has(item, 'value')) {
return item.value;
}
return (item.value = fn(args));
};
}
let counter = 1;
function foo() {
counter += 1;
return counter;
}
const id1 = Symbol('id');
const id2 = Symbol('id');
const memoizedFoo = memoize(foo);
console.log(memoizedFoo(id1)); // 2
console.log(memoizedFoo(id1)); // 2
console.log(memoizedFoo(id2)); // 3
console.log(memoizedFoo(id2)); // 3
Any help is greatly appreciated.
Unfortunately, if you're trying to "GET" a key, you cannot return the map, as you're asking for the key, so it must return the key. So you can't chain that method. But any method that shouldn't return something by default (IE would be void), we can do this:
cache = cache.getKey(key) || cache.setKey(key).get(key);
This will return a boolean, as the || symbol means return true if either is true.
But if you'd like to do the sort of chaining that JQuery does, that's easily achievable! What you want to do is return this or the object in every method.
Like so:
function isObject(arg) {
const typeOfObj = typeof arg;
return (typeOfObj === 'object' || typeOfObj === 'function') && arg !== null;
}
class Cache {
constructor() {
this.map = new Map();
this.weakmap = new WeakMap();
}
setKey(key) {
const map = this[isObject(key) ? 'weakmap' : 'map'];
map.set(key, new Cache());
return this; // HERE'S THE IMPORTANT PART
}
}
let counter = 1;
function foo() {
counter += 1;
return counter;
}
const id1 = Symbol('id');
const id2 = Symbol('id');
const memoizedFoo = memoize(foo);
console.log(memoizedFoo(id1)); // 2
console.log(memoizedFoo(id1)); // 2
console.log(memoizedFoo(id2)); // 3
console.log(memoizedFoo(id2)); // 3

Javascript code not giving any result

A days node with more than 1 child isn't getting removed. How can I fix this issue?
const theRef = event.data.ref;
const collectionRef = theRef.parent.child('days');
return collectionRef;
collectionRef.once('value').then(messagesData => {
if(messagesData.numChildren() > 1) {
let updates = {};
updates['/days'] = null;
return defaultDatabase.ref().update(updates); // 'days' doesn't get removed even if it has more than 1 child (as in the image)!
}
});
Data structure:
is it because you need to return collectionRef at the end not before calling once on collectionref?? so:
const theRef = event.data.ref;
const collectionRef = theRef.parent.child('days');
collectionRef.once('value').then(messagesData => {
if(messagesData.numChildren() > 1) {
let updates = {};
updates['/days'] = null;
return defaultDatabase.ref().update(updates); // 'days' doesn't get removed even if it has more than 1 child (as in the image)!
}
});
return collectionRef;

Categories