I have an async function that gets an array of objects, I set a soundOn to true if:
soundOn = content.some(ele => ele.order_status === 'processing');
It works partly, e.g. plays sound when above is true - however continues to play even if soundOn evaluates to false. Here's the rest of my code.
function getOrders()
{
(async () => {
bgSound = new Audio("assets/sounds/spn.mp3");
soundOn = "";
const resp = await fetch(url+'/app/v1/post', {
//truncated
});
const content = await resp.json();
if(content.length > 0)
{
soundOn = content.some(ele => ele.order_status === 'processing');
}
(soundOn) ? setInterval(function () { bgSound.play() }, 5000) : bgSound.pause();
})();
setTimeout(getOrders, 30000);
}
content array looks like this (part of it).
[{"id":"1","order_status":"acknowledged", "type":"off"},
{"id":"1","order_status":"processing", "type":"off"},{"id":"1","order_status":"processing", "type":"off"}]
while the app is running those statuses get updated to acknowledged but the sound continues to play. I am not sure why this is the case, any help would be appreciated.
Adding a condition might help:
(soundOn) ? setInterval(function () { if (soundOn) bgSound.play() }, 5000) : bgSound.pause();
Related
I have a main file that acts like an API to manage the playing, resuming or a video.
main.js
const { mainModule } = require('process');
const { startVideo, pauseVideo, stopVideo } = require('./modules/video.js');
function init(payload) {
if(payload.type === 'play') {
handlePlayVideo(payload.data)
} else if(payload.type === 'pause') {
handlePauseVideo(payload.data);
} else if(payload.type === 'stop') {
handleStopVideo(payload.data);
}
}
function handlePlayVideo(data) {
startVideo(data).then(() => {
console.log('Video state: play');
});
}
function handlePauseVideo(data) {
pauseVideo().then(() => {
console.log('Video state: pause');
});
}
function handleStopVideo(data) {
stopVideo().then(() => {
console.log('Video state: stop');
});
}
I want to be able to use the data every second when the state(payload.type) is 'play'. That would start my interval, but I'm stuck on how to be able to pause it (then continue later from the same second), or stop it.
This is what I've tried:
video.js
module.exports = (function () {
let currentSecond = 0;
let videoIsPaused = false;
let videoIsStopped = false;
function startVideo(data) {
const videoTicker = setInterval(() => {
if(videoIsPaused || videoIsStopped) {
console.log('video is paused or stopped');
clearInterval(videoTicker);
if(videoIsStopped) currentSecond = 0;
}
parseVideo(data.someData, currentSecond);
if(currentSecond === 100) clearInterval(scenarioTicker);
currentSecond++;
}, 1000);
}
function pauseVideo() {
videoIsPaused = true;
}
function videoIsStopped() {
videoIsStopped = true;
}
function parseVideo(data) {
// do something (stream) the data every second, except when the video is paused, or stopped
}
})();
With this code, the startVideo method starts executing every second, but I cannot pause it.
Update:
The starting of the video has been started(tested) using cli (ex. node main.js), which started the execution of start video for let's say one minute. In the same time, I'm opening a second cmd window, where I try to call the pauseVideo of the first window. So I think that my issue is because of the separate window environments which acts like a different scope, and I assume that my calls cannot interact with each other in this way. Is there a better way of doing/testing this?
In your if statement for the paused/stopped condition, you're not stopping the execution of the rest of the function. Therefore, the parts below it, like increasing currentSecond will still be hit. Perhaps an early return is what you need:
if(videoIsPaused || videoIsStopped) {
console.log('video is paused or stopped');
clearInterval(videoTicker);
if(videoIsStopped) currentSecond = 0;
return;
}
I am doing a time-to-click score table but first I have to localstorage each time I get in a game but I dont know how I have been trying everything but it still not working, I need to finish this fast, and I need help... otherwise I would try everyday to resolve this alone because I know that's the way to learn.. When I press the finished button It says that times.push() is not a function.
let times = Array.from(
{ length: 3 }
)
let interval2;
// Timer CountUp
const timerCountUp = () => {
let times = 0;
let current = times;
interval2 = setInterval(() => {
times = current++
saveTimes(times)
return times
},1000);
}
// Saves the times to localStorage
const saveTimes = (times) => {
localStorage.setItem('times', JSON.stringify(times))
}
// Read existing notes from localStorage
const getSavedNotes = () => {
const timesJSON = localStorage.getItem('times')
try {
return timesJSON ? JSON.parse(timesJSON) : []
} catch (e) {
return []
}
}
//Button which starts the countUp
start.addEventListener('click', () => {
timerCountUp();
})
// Button which stops the countUp
document.querySelector('#start_button').addEventListener('click', (e) => {
console.log('click');
times = getSavedNotes()
times.push({
score: interval2
})
if (interval) {
clearInterval(interval);
clearInterval(interval2);
}
})
You probably need to change the line times = JSON.parse(localStorage.times || []) to times = JSON.parse(localStorage.times) || [] this makes sure that if the parsing fails it will still be an array.
Even better is wrap them with try-catch just in case if your JSON string is corrupted and check if the time is an array in the finally if not set it to empty array.
I'm working with the below code to trigger a flash when fields change. All is well, except that my timeouts are not actually completing due to some javascript magic i do not understand. If anyone can shed light on why these timeouts would not be completing that would be very helpful - thanks!
I'm assuming it has something to do with using this inside of the loop?
componentDidUpdate(prevProps) {
const updates = {};
fields(this.props).forEach(f => {
if (!_.isEqual(this.props[f], prevProps[f])) {
updates[updatedKey(f)] = true;
}
});
if (Object.keys(updates).length > 0) {
this.setState({ ...updates });
Object.keys(updates).forEach(f => {
const tkey = timeoutKey(f);
clearTimeout(this[tkey]);
this[tkey] = setTimeout(() => this.setState({ [updatedKey(f)]: false }), 700);
});
}
}
Every minute I have a script that push a new record in my firebase database.
What i want is delete the last records when length of the list reach a fixed value.
I have been through the doc and other post and the thing I have found so far is something like that :
// Max number of lines of the chat history.
const MAX_ARDUINO = 10;
exports.arduinoResponseLength = functions.database.ref('/arduinoResponse/{res}').onWrite(event => {
const parentRef = event.data.ref.parent;
return parentRef.once('value').then(snapshot => {
if (snapshot.numChildren() >= MAX_ARDUINO) {
let childCount = 0;
let updates = {};
snapshot.forEach(function(child) {
if (++childCount <= snapshot.numChildren() - MAX_ARDUINO) {
updates[child.key] = null;
}
});
// Update the parent. This effectively removes the extra children.
return parentRef.update(updates);
}
});
});
The problem is : onWrite seems to download all the related data every time it is triggered.
This is a pretty good process when the list is not so long. But I have like 4000 records, and every month it seems that I screw up my firebase download quota with that.
Does anyone would know how to handle this kind of situation ?
Ok so at the end I came with 3 functions. One update the number of arduino records, one totally recount it if the counter is missing. The last one use the counter to make a query using the limitToFirst filter so it retrieve only the relevant data to remove.
It is actually a combination of those two example provided by Firebase :
https://github.com/firebase/functions-samples/tree/master/limit-children
https://github.com/firebase/functions-samples/tree/master/child-count
Here is my final result
const MAX_ARDUINO = 1500;
exports.deleteOldArduino = functions.database.ref('/arduinoResponse/{resId}/timestamp').onWrite(event => {
const collectionRef = event.data.ref.parent.parent;
const countRef = collectionRef.parent.child('arduinoResCount');
return countRef.once('value').then(snapCount => {
return collectionRef.limitToFirst(snapCount.val() - MAX_ARDUINO).transaction(snapshot => {
snapshot = null;
return snapshot;
})
});
});
exports.trackArduinoLength = functions.database.ref('/arduinoResponse/{resId}/timestamp').onWrite(event => {
const collectionRef = event.data.ref.parent.parent;
const countRef = collectionRef.parent.child('arduinoResCount');
// Return the promise from countRef.transaction() so our function
// waits for this async event to complete before it exits.
return countRef.transaction(current => {
if (event.data.exists() && !event.data.previous.exists()) {
return (current || 0) + 1;
} else if (!event.data.exists() && event.data.previous.exists()) {
return (current || 0) - 1;
}
}).then(() => {
console.log('Counter updated.');
});
});
exports.recountArduino = functions.database.ref('/arduinoResCount').onWrite(event => {
if (!event.data.exists()) {
const counterRef = event.data.ref;
const collectionRef = counterRef.parent.child('arduinoResponse');
// Return the promise from counterRef.set() so our function
// waits for this async event to complete before it exits.
return collectionRef.once('value')
.then(arduinoRes => counterRef.set(arduinoRes.numChildren()));
}
});
I have not tested it yet but soon I will post my result !
I also heard that one day Firebase will add a "size" query, that is definitely missing in my opinion.
How can I check if an element exists in selenium?
I have tried:
browser.driver.findElements(by.id('my-id'))
but it does not seem to work.
Use isElementPresent
browser.driver.isElementPresent(by.id('my-id'))
or isPresent
element(by.id('my-id')).isPresent()
The problem is looking for an element that does not exist throws an exception. You ar eon the right track with using findElements as this will not throw an error if it cannot find the element, the problem you have is being left with a list that contains the elements found but not comparing to make sure that there is at least 1 element in the list (e.g. it found one element)
public boolean exists(By by){
return !driver.findElements(by).isEmpty();
}
is a function that will return true if it exists, false otherwise. Its clear from this method how you could modify it to suit your need.
webdriver.js example
In this example I am waiting for a modal to exist because its a modal that fades in
See the line that reads
const doesModalFadeInExist = await this.driver.executeScript('return document.getElementsByClassName("modal fade in")');
You can put this line of code in a wait that waits for the element array to be >=1
This way you know it is there after checking inside the wait.
We can also check opacity at the same time.
Once the element array >=1 and opacity = '1' . then we exit the wait and continue the test
async waitForModalFadeIn() {
try {
let isVisible;
let opacityReturned;
let isModalFadeInFound;
const dialog = await this.driver.wait(until.elementLocated(this.baseselector.MODAL_FADE_IN));
await this.driver.wait(async () => {
const doesModalFadeInExist = await this.driver.executeScript('return document.getElementsByClassName("modal fade in")');
isModalFadeInFound = doesModalFadeInExist;
const bool = await this.isDisplayed(this.baseselector.MODAL_FADE_IN);
isVisible = bool;
const opacity = await dialog.getCssValue('opacity');
opacityReturned = opacity;
return isVisible === true && isModalFadeInFound.length > 0 && opacity === '1';
}, 4000);
return opacityReturned === '1' && isVisible === true && isModalFadeInFound.length > 0;
} catch (err) {
console.log(`Function waitForModalFadeIn: Failed to open modal${err}`);
return null;
}
}
Example Test
it('Trigger "unmetered" modals in the technical spec section', async () => {
await wHost.visit(page = '/web-hosting');
const table = await driver.wait(until.elementLocated(wHost.selector.COMPETITOR_TABLE), this.pageLoadTimeOut);
await driver.executeScript('arguments[0].scrollIntoView()', table);
const modals = await table.findElements(wHost.selector.UNLIMITED_MODAL);
for (let i = 0; i < modals.length; i++) {
await modals[i].click();
assert.isTrue(await common.waitForModalFadeIn());
assert.isTrue(await common.closeModal());
}
});
This is what you are looking for, This function takes id as parameter,
If the element is found it returns json object with status=true and element you were looking for.
async function ElementExistsID(element){
return new Promise(async (resolve)=>{
try{
let ElementResult=await driver.findElement(webdriver.By.id(element));
resolve({"element":ElementResult,"status":true});
}
catch(error){
log.warn(error);
resolve({"status":false});
}
})
}
You can use it like this
let ElementIamLookingFor=await ElementExistsID(IDOfTheElement);
if(ElementIamLookingFor.status){
console.log("Element exists");
}
else{
throw new Error("Element not found");
}
After many attempts, the following worked for me:
function doIfPresent(elementId, doIfPresent, next) {
var elem = by.id(elementId);
browser.driver.isElementPresent(elem).then(function (present){
if (present) {
doIfPresent(element(elem));
}
next();
});
}
eg.
doIfPresent('my-button', function(element){ element.click();}, function(){
// your code continues here
});
I don't get it though why we'd need to use futures here.