Redux saga Firebase callback - react-native

I am trying register a firebase callback using redux-saga in react-native but I am not able to figure out how (I am new to redux-saga). Below is the code I want to write in redux saga:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('user logged')
}
});

Wrap your firebase call in a promise like so:
// firebase.js
export function onAuthStateChanged() {
return new Promise((resolve, reject) => {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
resolve(user);
} else {
reject(new Error('Ops!'));
}
});
});
}
// in your app
import { onAuthStateChanged } from './firebase';
function * saga() {
try {
const user = yield call(onAuthStateChanged);
// ...
} catch (error) {
console.error(error);
}
}

Related

How to clean up React-Native useEffect with axios

Currently I have defined in a functional component a useEffect as below
useEffect(() => {
(async function () {
posts.current = await BlogConsumer.getBlogPosts();
setLoading(false);
})();
return () => {
BlogConsumer.call_controller.abort();
};
}, []);
where this BlogConsumer is defined as below
class BlogConsumer {
static posts = {};
static call_controller = new AbortController();
static async getBlogPosts() {
await axios
.get('https://nice.api', {
signal: this.call_controller.signal,
})
.then(response => {
// treatment for success
})
.catch(error => {
// treatment for erros
});
return this.posts;
}
}
export default BlogConsumer;
The overral ideia is that in the render of the component I'll be calling a static method from my consumer and will retrieve the necessary data. For the pourpuse of not having memory leaks, I have my callback function in my useEffect that will abort my call whenever I unmount the component, but this is not working. React's message of Warning: Can't perform a React state update on an unmounted component. still appears if I enter the component and leave the screen before the API call is finished. I don't know where I am wrong, so I'd like a little help.
Thanks in advance.
You could just cancel the request on unmount. Like this:
export const fetchData = async (signal) => {
try {
const res = await instance.get("/pages/home", {
signal,
});
return res.data;
} catch (error) {
return Promise.reject(error);
}
};
useEffect(() => {
const controller = new AbortController();
fetchData(controller.signal);
return () => {
controller.abort()
};
}, []);

Nuxt fetch hook api can't access the api folder

I have an api that I call in my fetch() hook:
pages/pageOne.vue:
async fetch() {
const { store, error } = this.$nuxt.context;
try {
await store.dispatch("folderOne/apiOne", null, { root: true });
} catch (e) {
error({
message: "error"
});
}
}
then in my store I have apiOne action setup like this:
store/folderOne/index.js:
//importing the api file here
const actions = {
apiOne({ commit }) {
apiFile.apiOne().then(data => {
if(data && data.status === 200){
// then commit
}
})
.catch(error => {
console.log(error);
});
},
}
Then I have a file for my APIs setup like this:
api/apiFile.js:
import axios from "axios";
const httpClient = axios.create({
headers: {
key: 'value
}
});
const baseUrl = process.env.config.baseUrl;
export default {
apiOne() {
return httpClient.get(`${baseUrl}values);
},
}
It doesn't work. But when I call the same apiOne in a #click method it works. Anyone knows what's is wrong and how can I fix it?
your store is and should be a global construct of your application.
it means when you call for a action and your setup is correct, you don't have to handle directives/folders by yourself.
in your case all you should do is dispatch the action in your component like this:
async fetch() {
const { store, error } = this.$nuxt.context;
try {
await store.dispatch("apiOne", null, { root: true });
} catch (e) {
error({
message: "error"
});
}
}

How can I return error message from axios function inside Vuex action to dispatch catch(error)?

I have an action where ajax call is made using axios,whenever the axios returns errors it gets catch by axios catch function , so i want to know if its possible to throw that same error to dispatch catch function.
I've tried to //throw new Error("test error inside"); from inside of axios catch(error) but dispatch doesnot seem to catch the error
Action code on vuex store
actions:{
assignOrder(context, assign){
axios.post('/assignOrder',assign)
.then((response) => {
console.log(response)
})
.catch((error) => {
//I want to throw error catched from here
console.log(error.response.data.errors)
//throw new Error("test error inside");
// }
})
}
}
On my method on vue component
methods:{
setAssign(){
this.assign.order_id = this.order.id
if(this.validate()){
this.errors = {};
this.$store.dispatch('assignOrder', this.assign).then(() => {
showNotify('success','Order has been assigned')
this.$store.dispatch('getOrders',this.active)
})
.catch((error) => {
//catch the error here
alert(error)
})
}
else{
this.showErr = true;
}
},
}
I want the axios to throw catch error which will catch by dispatch
Just return a promise from your action then handle that on your component :
actions: {
assignOrder(context, assign) {
return new Promise((resolve, reject) => {
axios.post('/assignOrder', assign)
.then((response) => {
resolve(response)
})
.catch((error) => {
reject(error.response.data.errors)
})
})
}
}
and on your component :
methods: {
setAssign() {
this.assign.order_id = this.order.id
if (this.validate()) {
this.errors = {};
this.$store.dispatch('assignOrder', this.assign).then((res) => {
showNotify('success', 'Order has been assigned')
console.log(res)
this.$store.dispatch('getOrders', this.active)
})
.catch((error) => {
// catch the error
alert(error)
})
} else {
this.showErr = true;
}
},
}
The promise will return either a resolve or a reject which will be bound to your then or catch
You can just return Promise in action and handle the response/error in method
vuex store:
actions:{
assignOrder(context, assign){
return axios.post('/assignOrder',assign)
}
}
and in your component do the following:
methods:{
setAssign() {
this.assign.order_id = this.order.id
if (this.validate()) {
this.errors = {};
this.$store.dispatch('assignOrder', this.assign).then(() => {
showNotify('success','Order has been assigned')
this.$store.dispatch('getOrders', this.active)
}).catch((error) => {
//catch the error here
alert(error)
})
} else{
this.showErr = true;
}
},
}

SecureStore is skipped while I am accessing the login function and returns function error

When I call loginUser function it suppose so access the SecureStore function but instead it is returning the from axios.post method.
Any idea what is going wrong here?
import { SecureStore } from 'expo';
export function loginUser(email, password) {
return function (dispatch) {
return axios.post(SIGNIN_URL, { email, password }).then((response) => {
var { user_id, token } = response.data;
Expo.SecureStore.setItemAsync(user_id, password, options).then(function() {
dispatch(authUser(user_id));
console.log('I am in')
}).catch((error) => {
console.log('Its an error')
dispatch(addAlert("Could not log in."));
});
}).catch((error) => {
dispatch(addAlert("Could not log in."));
});
};
}
The issue is with the way you are constructing your promise chain.
const promiseOne = new Promise((resolve, reject) => {
resolve('p1')
})
const promiseTwo = new Promise((resolve, reject) => {
resolve('p2')
})
promiseOne.then(
(res) => {
console.log('res', res)
return promiseTwo
})
.then((res2) => {
console.log('res2', res2)
})
basically you need to return the call to Expo

react native giving localstorage getItem not a function error

I was trying to use the Async Storage official react native API. The code in my react native looks like this:
export function get(key) {
return new Promise(function(resolve, reject) {
AsyncStorage.getItem(key, (err, val) => {
if (err) {
reject(err)
} else {
if (val === null) {
reject('key_not_found')
} else {
var parsedVal = JSON.parse(val)
console.log('got value from storage =>', parsedVal);
resolve(parsedVal)
}
}
})
});
}
I worked for a week without any problem, but recently it starts to give this error
The logger output from remote JS debugger looks like this
I didn't change any of the npm modules except that I installed moment.js using npm install --save moment Any idea what might be happening here?
UPDATE:
The places where I used this exported function are:
//This one is inside the same file so I just use get without module name
export function retrieveCredential() {
return new Promise(function(resolve, reject) {
get('credential')
.then((val) => {
resolve(val)
})
.catch((err) => {
console.log(err)
reject(err)
})
});
}
//this function is also exported
export function autoLogin() {
return new Promise(function(resolve, reject) {
LocalStorage.retrieveCredential()
.then((credential) => {
loginWithEmail (credential.email, credential.password, false)
.then(() => {
resolve()
})
.catch((err) => {
console.log(err)
reject(err)
})
})
.catch((err) => {
console.log(err)
reject(err)
})
});
}
//This is finally used in one of the component
Authentication.autoLogin()
.then(() => { ... })
.catch(() => { ... })
Project search for localstorage.getItem result: