App crash only if im not using debugger. Unable to overcome the situation. What should I do? - react-native

I'm facing a pretty ugly issue that I'm not able to overcome by myself, I just don't get it.
A short summary of my app purpose: You can find food around and make orders to restaurant owners.
I wrote a helper function that allows me to decide if the restaurant is open or closed based on its schedule “horarioSemanal” property.
This function take the restaurants queried from firestore as arguments and depending in some conditions it decide which value of the property “disponible” (available) it deserves.
The thing is that it works pretty well! So well that I published the changes through expo, and as expo has updates over-the-air and I have my app in both apptore and Google play it reached all my users…
None of my users were able to use my app until I removed the changes because I was unable to detect the issue. In my simulator it worked 100% but when the app was deployed crashed almost instantly.
Testing, testing, and testing I finally come to the issue but I still can't figure out what the hell should I do to overcome this situation.
The app while I use the js debugger it works perfectly! but when I turned off this new module I wrote doesn't work.
I recorded a video so you can see the same I'm watching on my screen:
https://www.youtube.com/watch?v=x9-t8-3XzKc
this is the action where im dispatching the action:
import { restaurantesHorarioValidado, validaDisponibilidadComidas } from '../../src/3-ResultadosComponents/Librerias/DisponibilidadHorario';
export const searchResultsInLocation = (ubicacion) => {
const db = firebase.firestore();
const docRef = db.collection('Restaurantes').where('abierto', '==', true).where(`zonaOperativa.zonaConsulta.${ubicacion}`, '==', true).get();
const restaurantesIDS = [];
return (dispatch) => {
const holder = [];
dispatch({
type: BUSQUEDA_DE_RESULTADOS,
});
docRef.then(querySnapshot => {
querySnapshot.forEach(doc => {
holder.push(doc.data());
restaurantesIDS.push(doc.data().id);
});
dispatch({
type: DESCARGA_RESTAURANTES_ABIERTOS,
restaurantes: restaurantesHorarioValidado(holder)
});
})
.then(() => {
const comidasRefs = [];
restaurantesIDS.forEach(restaurant => {
const ref = db.collection('Comidas').where('restaurantID', '==', `${restaurant}`).get();
comidasRefs.push(ref);
});
return Promise.all(comidasRefs).then(results => {
const comidas = [];
results.forEach(resto => {
resto.forEach(comida => comidas.push(comida.data()));
});
dispatch({
type: DESCARGA_COMIDAS,
comidas: validaDisponibilidadComidas(comidas, restaurantesHorarioValidado(holder))
});
})
.then(() => dispatch({
type: BUSQUEDA_DE_RESULTADOS,
}))
.catch(err => console.log('error; ', err));
});
};
};
here is how the reducer is handling the action:
case DESCARGA_COMIDAS:
return { ...state, comidas: action.comidas };
case DESCARGA_RESTAURANTES_ABIERTOS:
return { ...state, restaurantes: action.restaurantes };
this is the module I wrote and I'm using to create the object that the action creator send:
const diasDeSemana = ['Domingo', 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado'];
const today = new Date().getDay();
const hoyAbre = (horario) => {
if (horario) {
const JornadaHoy = horario.find(jornada => jornada.dia == diasDeSemana[today]);
return JornadaHoy;
}
return false;
};
export const isRestaurantAvalaible = (horario) => {
const Today = new Date();
if (hoyAbre(horario)) {
//Si el restaurant abre hoy
//Evalua si está abierto
const horarioApertura = () => {
const nuevoDia = new Date(`${Today.getFullYear()}, ${Today.getMonth() + 1} ${Today.getDate()} ${hoyAbre(horario).horario.apertura}:00`);
return nuevoDia;
};
const horarioCierre = () => {
//Si horario de cierre es hoy
const nuevoDia = new Date(`${Today.getFullYear()}, ${Today.getMonth() + 1} ${Today.getDate()} ${hoyAbre(horario).horario.cierre}:00`);
//Si el horario de cierre de hoy es pasado las 00:00
const cierraTomorrow = new Date(`${Today.getFullYear()}, ${Today.getMonth() + 1} ${Today.getDate() + 1} ${hoyAbre(horario).horario.cierre}:00`);
if (nuevoDia.getHours() <= 8) {
return cierraTomorrow;
}
return nuevoDia;
};
const isNowOpen = Today.getTime() >= horarioApertura().getTime();
const isNowClosed = Today.getTime() >= horarioCierre().getTime();
//Si está abierto
if (isNowOpen && !isNowClosed) {
return { estado: 'abierto' };
}
//Si abre mas rato
if (hoyAbre(horario) && (Today.getTime() < horarioApertura())) {
return { estado: 'abre pronto', horarioApertura: horarioApertura() };
}
//Si ya cerró
if (isNowOpen && isNowClosed) {
return { estado: 'ya cerro', horarioCierre: horarioCierre() };
}
}
//Si hoy no abre
if (!hoyAbre(horario)) {
return { estado: 'No abre hoy' };
}
};
export const restaurantesHorarioValidado = (restaurantes) => {
const restaurantesModificados = restaurantes.map(restaurant => {
return { ...restaurant, disponible: isRestaurantAvalaible(restaurant.horarioSemanal) };
});
const restaurantesAbiertos = restaurantesModificados.filter(restaurant => restaurant.disponible.estado == 'abierto');
const restaurantesProximosAbrir = restaurantesModificados.filter(restaurant => restaurant.disponible.estado == 'abre pronto');
const restaurantesCerrados = restaurantesModificados.filter(restaurant => restaurant.disponible.estado == ('ya cerro' || 'No abre hoy'));
return [...restaurantesAbiertos, ...restaurantesProximosAbrir, ...restaurantesCerrados];
};
export const validaDisponibilidadComidas = (comidas, restaurantes) => {
//Se le agrega la propiedad "disponible" del restaurant dueño
const comidasModificadas = comidas.map(comida => {
const Owner = restaurantes.find(restaurant => restaurant.id == comida.restaurantID);
return { ...comida, disponible: Owner.disponible };
});
const comidasDisponibles = comidasModificadas.filter(comida => comida.disponible.estado == 'abierto');
const comidasProximosAbrir = comidasModificadas.filter(comida => comida.disponible.estado == 'abre pronto');
const comidasNoDisponibles = comidasModificadas.filter(comida => comida.disponible.estado == ('ya cerro' || 'No abre hoy'));
return [...comidasDisponibles, ...comidasProximosAbrir, ...comidasNoDisponibles];
};
this is the error I get once I turned off the js debugger:
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'restaurant.disponible.estado')]
Stack trace:
src/3-ResultadosComponents/Librerias/DisponibilidadHorario.js:65:98 in <unknown>
src/3-ResultadosComponents/Librerias/DisponibilidadHorario.js:65:62 in restaurantesHorarioValidado
store/actions/2-ResultadosActions.js:55:50 in <unknown>
node_modules/promise/setimmediate/core.js:37:14 in tryCallOne
node_modules/promise/setimmediate/core.js:123:25 in <unknown>
...
As it suggest there is some error with promises I tried making those functions work as promises. The errors disappear but the I didn't get the object back...
The question is this How the hell may this work just when the debugger it's on and not when it's turned off?
what should I do to get my life back?

Related

Async function react native

We have to create a Bingo game in React Native with Firebase Realtime Database on Android simulator. The app game is for 2 players. When the first player enter in the app, he create the game and wait for the second player to join.
we want to create a screen with the writing: "Waiting for another player" that appears to the first player until the second player connects then when the second player connects the card is shown.
We wrote this code but it return 'undefined' .
function Game(){
const authCtx = useContext(AuthContext);
const gameCtx = useContext(GameContext);
const [loadPlayer, setLoadPlayer] = useState(false);
useEffect(() => {
async function gamePlay(){
gameCtx.player1 = authCtx.token;
const play = await setGame(authCtx.token, gameCtx);
console.log(play); //return undefined
if(play == 'CREATE'){
setLoadPlayer(true);
}else if(play == 'UPDATE'){
setLoadPlayer(false);
}
if(loadPlayer){
return <LoadingOverlay message="Waiting for another player... " />;
}
}
gamePlay();
}, []);
return <Card />;
}
export default Game;
export function create(game){
const db = getDatabase();
const newGameKey = push(child(ref(db), 'GAME')).key;
set(ref(db, '/GAME/' + newGameKey), game)
.then(() => {console.log('Game Create!');})
.catch((error) => {console.log(error);});
}
export function setGame(email, game){
const dbRef = ref(getDatabase());
var player = false;
get(child(dbRef, 'GAME/')).then((snapshot) => {
if (snapshot.exists()) {
snapshot.forEach(function(childSnapshot) {
const key = childSnapshot.key;
const key1 = snapshot.child(key + '/player1').val();
const key2 = snapshot.child(key + '/player2').val();
if( key2 == "" && email != key1){
console.log('P2');
updateGame(email, key);
player = true;
return true;
}
});
if(player == false){
console.log('P1');
player = true;
create(game);
}
} else {
//create the first game!
create(game);
}
}).catch((error) => {
console.error(error);
});
}
export function updateGame(email, key){
console.log('Update: ' + key);
const db = getDatabase();
const updates = {};
updates['/GAME/' + key + '/player2'] = email;
return update(ref(db), updates);
}
We think this is due to "async" and "await" because not working correctly.
Do you have any suggestions?
How can we redirect the first player to a waiting screen?
is ref(getDatabase()) is promise?. if it is then use await before it.
and use async function before setGame if you are using await while calling.
export async function setGame(email, game){
const dbRef = await ref(getDatabase());
var player = false;
get(child(dbRef, 'GAME/')).then((snapshot) => {
if (snapshot.exists()) {
snapshot.forEach(function(childSnapshot) {
const key = childSnapshot.key;
const key1 = snapshot.child(key + '/player1').val();
const key2 = snapshot.child(key + '/player2').val();
if( key2 == "" && email != key1){
console.log('P2');
updateGame(email, key);
player = true;
return true;
}
});
if(player == false){
console.log('P1');
player = true;
create(game);
}
} else {
//create the first game!
create(game);
}
}).catch((error) => {
console.error(error);
});
}

ProtocolError: Protocol error (Runtime.callFunctionOn): Target closed. - express.js and puppeteer-cluster

I want to iterate over key-pairs of data.extractRules and get elements data from the page.
This snippet inside forEach loop is causing app crashes. I tried hardcoding key and cssSelector and tried this outside of forEach loop and it worked.
const extractContent = {};
if (data.extractRules !== null) {
Object.entries(data.extractRules).forEach(async ([key, cssSelector]) => {
extractContent[key] = await page.$$eval(cssSelector, (elements) =>
elements.map((element) => element.outerHTML)
);
});
}
I figured out solution 😁
async function getSelectorContent(page, cssSelector) {
return page.$$eval(cssSelector, (elements) =>
elements.map((element) => element.outerHTML)
);
}
const extractContent = {};
if (data.extractRules !== null) {
await Object.entries(data.extractRules).reduce(
async (item, [key, cssSelector]) => {
await item;
extractContent[key] = await getSelectorContent(page, cssSelector);
},
Promise.resolve()
);
}

Message event broken ( quick.db )

So i wanna get started with quick.db for my discord.js bot. I asked someone to help me solve this issue but they seem to be unable to. So if theres anyone here that can help could you tell me whats wrong with my code
module.exports = (client) => client.on('messageCreate', async (message) => {
const prefix = [].concat(client.config.prefix);
const ms = require('ms');
if (
message.author.bot ||
!message.guild ||
!prefix.some((x) => message.content.toLowerCase().startsWith(x))
)
return;
const [cmd, ...args] = message.content
.slice(prefix
.filter((x) => message.content.toLowerCase().startsWith(x))
.sort((a, b) => b.length - a.length)[0].length
)
.trim()
.split(/ +/g);
const command =
client.commands.get(cmd.toLowerCase()) ||
client.commands.find((c) =>
[].concat(c.aliases).includes(cmd.toLowerCase())
);
if (!command) return;
const cd = client.cd.get(`${message.author.id}_${command.name}`);
const left = cd - Date.now();
if (left > 0) {
const msg = await message.channel.send(
`You are on cooldown, please wait **${ms(left)}** to use this command again`
);
return setTimeout(() => msg.delete(), left);
}
if (command.cooldown)
client.cd.set(
`${message.author.id}_${command.name}`,
Date.now() + ms(command.cooldown)
);
try {
await command.run(client, message, args);
} catch (error) {
message.channel.send(error.toString());
}
}); 
the above code is the working one but whenever i use this
module.exports = (client) => client.on('messageCreate', async (message) => {
const ms = require('ms');
const { QuickDB } = require('quick.db');
const db = new QuickDB();
const prefix = db.get(`newprefix_${message.guild.id}`) || config.prefix
if (!prefix) return; 
if (!message.content.startsWith(prefix) || message.author.bot) return;
const [cmd, ...args] = message.content
.slice(prefix
.filter((x) => message.content.toLowerCase().startsWith(x))
.sort((a, b) => b.length - a.length)[0].length
)
.trim()
.split(/ +/g);
const command =
client.commands.get(cmd.toLowerCase()) ||
client.commands.find((c) =>
[].concat(c.aliases).includes(cmd.toLowerCase())
);
if (!command) return;
const cd = client.cd.get(`${message.author.id}_${command.name}`);
const left = cd - Date.now();
if (left > 0) {
const msg = await message.channel.send(
`You are on cooldown, please wait **${ms(left)}** to use this command again`
);
return setTimeout(() => msg.delete(), left);
}
if (command.cooldown)
client.cd.set(
`${message.author.id}_${command.name}`,
Date.now() + ms(command.cooldown)
);
try {
await command.run(client, message, args);
} catch (error) {
message.channel.send(error.toString());
}
});  
it doesn't work, meaning my bot doesn't reply

How do I resolve a callback error with 'callback' is an instance of Object)?

TypeError: callback is not a function. (In 'callback(data)',
'callback' is an instance of Object)
The code here works just fine when I write it like this:
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
// { categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
When i uncomment that other line, it breaks and gives me this error.
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
{ categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
Here is the relevant snippet from listingsAPI (below) if it helps but this code works fine when there is only one object. Is there a specific way to make this work with two objects like above?
if (categoryId) {
return (
listingsRef
.where('categoryID', '==', categoryId)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
if (categoryId2) {
return (
listingsRef
.where('categoryID2', '==', categoryId2)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
You can combine your queries via this way if you want to have it optional:
let query = listingsRef.where('isApproved', '==', isApproved)
if (categoryId) {
query = query.where('categoryID', '==', categoryId)
}
if (categoryId2) {
query = query.where('categoryID2', '==', categoryId2)
}
query.onSnapshot...

How to write unit test component with FileReader.addEventListener in angular 8?

I use angular 8 and i want to test my component with FileReader.
I can not test a FileReader in my processFile function.
Maybe my work is badly written? Can you help me please to understand.
IF I understand correctly, I have to test a class (Filereader) in a process function
my component
processFile(imageInput: any) {
const file: File = imageInput.files[0];
const reader = new FileReader();
let size: number = 2097152
if (file) {
if (file.size <= size) {
this.sharingDataService.setUploadIsOk(true)
reader.addEventListener('progress', (event:any) =>{
this.progressValue = this.progressBar(event)
if (event.lengthComputable) {
// console.log(event.loaded+ " / " + event.total)
}
})
reader.addEventListener('loadstart', (event:any) =>{
this.progressValue =0;
this.textDuringUploadBefore = "No"
this.textDuringUploadAfter = ''
// console.log('start');
})
reader.addEventListener('loadend', (event:any) =>{
// console.log('end');
})
reader.addEventListener('load', (event: any) => {
console.log(event);
this.selectedFile = new ImageSnippet(event.target.result, file);
this.fileName = this.selectedFile.file.name;
this.fileNameExt =this.fileName.split('.').pop();
this.displayAddPhoto = false;
this.selectedFile.status = 'ok';
this.getLoadCallBack(file)
// this.ng2ImgMax.resizeImage(file, 900,600).subscribe(
// result =>{
// // console.log('compress', );
// this.textDuringUploadAfter= "Yes!!!"
// this.textDuringUploadBefore= ''
// this.fileForm.patchValue({
// image: new File([result], result.name)
// });
// this.imageIsLoad = true
// this.sharingDataService.setUploadIsOk(false)
// }
// )
// this.imageOutput.emit(this.fileForm)
});
reader.readAsDataURL(file);
} else {
const msg ="This picture is too big."
+ '<br/>' + "Please upload an image of less than 2MB."
// this.sharedFunctionService.openDialogAlert(msg, 'home')
this.errorService.openDialogError(msg)
this.imageIsLoad = false
this.sharingDataService.setUploadIsOk(false)
}
}
}
getLoadCallBack(file:File){
this.ng2ImgMax.resizeImage(file, 900,600).subscribe(
result =>{
// console.log('compress', );
this.textDuringUploadAfter= "Yes"
this.textDuringUploadBefore= ''
this.fileForm.patchValue({
image: new File([result], result.name)
});
console.log(this.fileForm);
this.imageIsLoad = true
this.sharingDataService.setUploadIsOk(false)
}
)
this.imageOutput.emit(this.fileForm)
}
my spec.ts
it('processFile', () => {
// const mockEvt = { target: { files: [fileInput] } };
// const mockReader: FileReader = jasmine.createSpyObj('FileReader', ['readAsDataURL', 'onload']);
// spyOn(window as any, 'FileReader').and.returnValue(mockReader);
// spyOn(component, 'getLoadCallBack').and.callThrough();
const file = new File([''], 'test-file.jpg', { lastModified: null, type: 'image/jpeg' });
const fileInput = { files: [file] };
const eventListener = jasmine.createSpy();
spyOn(window as any, "FileReader").and.returnValue({
addEventListener: eventListener
})
component.processFile(fileInput);
i have got an error
TypeError: reader.readAsDataURL is not a function
how to test my processFile function?
I trie many way but no sucess