How to prevent multi beginTransactions in Realmjs? - react-native

I create a function to handle transaction, then I call it to multi places. I got crash when another transaction not yet complete when I open new transaction.
Here my code:
const RealmMakeTransaction = async (action) => {
try {
realm.GetInstance().beginTransaction();
let response = await action();
realm.GetInstance().commitTransaction();
return response;
} catch (e) {
realm.GetInstance().cancelTransaction();
}
};

You can easily check if realm is already in transaction or not before calling beginTransaction() by calling realm.GetInstance().isInTransaction
Your code will look like :
const RealmMakeTransaction = async (action) => {
//use single instance
let realm = realm.GetInstance();
try {
if( realm.isInTransaction)
realm.cancelTransaction();
realm.beginTransaction();
let response = await action();
realm.commitTransaction();
return response;
} catch (e) {
realm.cancelTransaction();
realm.close();
}
};

Related

Sequelize, findOrCreate + findAll unexpected behavior

I'm trying to fetch data from a dog API and I want to add to my database only their temperaments. I tried using some loops and a split to isolate the data and then using
findOrCreate() to add only those who are not already in the DB, after that I use findAll()
to get that info from the DB to send it using expressJS.
The unexpected behavior comes when I go to the route that executes all this and the route
only gives about half of the temperaments (they are 124 and it displays arround 54), then when I refresh the page it shows all 124 of them. The DB gets populated with all the 124 in one go so the problem is with findAll()
This is the function that isolates the temperaments and append them to the DB:
module.exports = async () => {
const info = await getAllDogs();
info.forEach(async (element) => {
const { temperament } = element;
if (temperament) {
const eachOne = temperament.split(", ");
for (i in eachOne) {
await Temperament.findOrCreate({
where: { name: eachOne[i] },
});
}
}
});
};
And this is the code that gets executed when I hit my expressJS sv to get the info
exports.temperaments = async (req, res) => {
try {
await getTemperaments(); //this function is the above function
} catch (error) {
res.status(500).send("something gone wrong", error);
}
const temperamentsDB = await Temperament.findAll();
res.json(temperamentsDB);
};
So as you can see the last function executes the function that appends all the data to the DB and then sends it with findAll and res.json()
forEach is a synchronous method so it doesn't await a result of the async callback. You need to do for of in order to get wait for all results:
module.exports = async () => {
const info = await getAllDogs();
for (element of info) {
const { temperament } = element;
if (temperament) {
const eachOne = temperament.split(", ");
for (i in eachOne) {
await Temperament.findOrCreate({
where: { name: eachOne[i] },
});
}
}
}
};

unable to read object (Can't find variable error)

In my below code, I stored an object in AsyncStorage in React Native, but I have a problem reading it inside {personValue}. I got
Can't find variable personValue
Error. could you help me to run my code?
const storeData = async () => {
try {
const newperson = JSON.stringify(person);
await AsyncStorage.setItem("#Key", newperson);
alert(newperson);
} catch (e) {
}
};
const getData = async () => {
try {
const personValue = await AsyncStorage.getItem("#Key");
if (personValue !== null) {
console.log(JSON.parse(personValue));
return JSON.parse(personValue);
}
} catch (error) {
}
in the console, I can see the object correctly in GetData method
P.S: I found the mistake I made. I parsed the wrong variable.
const getData = async () => {
try {
const personValue = await JSON.parse(AsyncStorage.getItem("#Key"));
if (personValue !== null) {
console.log(personValue);
return personValue;
}
}

SpeechSynthesizer.speakTextAsync callback when it's finished

I'm facing the issue with Azure speakTextAsync callback issue it's azure SpeechSDK support?
Here is the sample link -> You can check
Code
try
{
var player = new SpeechSDK.SpeakerAudioDestination();
var audioConfig = SpeechSDK.AudioConfig.fromSpeakerOutput(player);
var speechConfig = SpeechSDK.SpeechConfig.fromSubscription("KEY", "REGION");
speechConfig.speechSynthesisLanguage = getCurrentLanguageCode();
synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig, audioConfig);
synthesizer.speakTextAsync(
inputText,
function (result) {
console.log(result)
if (result.reason === SpeechSDK.ResultReason.SynthesizingAudioCompleted) {
//some callback
}
synthesizer.close();
},
function (err) {
synthesizer.close();
})
synthesizer.synthesisCompleted = function (s, e) {
console.log(s)
console.log(e)
//some callback
};
} catch (e) {
console.log(e.message);
}
In this, I've tried two ways
SpeechSDK.ResultReason.SynthesizingAudioCompleted
synthesizer.synthesisCompleted
But both are called when the speakTextAsync method call.
I've found the solution
Just need to add the code
Player code
player.onAudioEnd = function () {
console.log('speakTextAsync finished');
}
Full speak code
synthesizer.speakTextAsync(
inputText,
function (result) {
synthesizer.close();
player.onAudioEnd = function () {
console.log('speakTextAsync finished');
}
},
function (err) {
synthesizer.close();
})

React native AsyncStorage bad response

Have created React Native app and ned to use AsyncStorage to benefit from it's storage mechanism.
To save in AsyncStorage use code:
_storeData = async (param) => {
try {
let par = JSON.stringify(param);
//await AsyncStorage.setItem(this.key, par);
Utilities.setItem(this.key, par);
this._retrieveData();
} catch (error) {
console.log(JSON.stringify(error));
}
};
To retrieve data:
_retrieveData = async () => {
try {
const value = Utilities.getItem(this.key);
if (value !== null) {
alert('data is new: ' + JSON.stringify(value));
}
} catch (error) {
}
};
And, to setItem and getItem in Utilities partial:
const setItem = (key, value) => {
if (!key || !value) return;
AsyncStorage.setItem(key, value);
};
const getItem = (key) => {
if (!key) return;
var val = AsyncStorage.getItem(key);
return val;
};
Data is being saved, but response I'm getting does not look correctly, as it's a string of 'weird' characters:
{"_40":0,"_65":0,"_55":null,"_72":null}
Does anybody know why I'm getting such answer?
Note that AsyncStorage.getItem is also async - the weird characters represent the promise being returned by getItem.
Use var val = await AsyncStorage.getItem(key); and mark your getItem utility function as async. You'll need to await on any calls to Utilities.getItem and Utilities.setItem as well.

cannot change observable from try catch block in mobx strict mode

class Someclass {
#observable waiting = false;
#observable error = null;
#action.bound
async authenticate({login, password}) {
try {
this.waiting = true;
const res = await myService.authenticate(login, password);
} catch (error) {
this.error = error; // Gives an error: Invariant Failed
} finally {
this.waiting = false; // Gives an error: Invariant Failed
// I've tried doing this too
// action(() => {
// this.waiting = false;
// })
}
}
}
In above example altering values from catch and finally block gives an error or warning Invariant Failed with strict mode. What is the correct way ?
Inside of async function we must wrap a function inside runInAction utility method for mutating #observable in strict mode. Example.
class Someclass {
#observable waiting = false;
#observable error = null;
#action.bound
async authenticate({login, password}) {
try {
this.waiting = true;
const res = await myService.authenticate(login, password);
} catch (error) {
runInAction(() => {
this.error = error;
});
} finally {
runInAction(() => {
this.waiting = false;
});
}
}
}
View this related issue on github