Inifinite loop while accessing redux store - react-native

I am trying to creat an app and in the current module, I need to get the list of productList from redux store. But when I try to read from the store the entire component started an infinit loop. If I comment the below line, everything becomes normal. I am new to React Native and I don't know what I am doing wrong here
const vendorProducts = useSelector(store => store.productList.loadedProducts);
import React, {useState, useEffect} from 'react';
import {View, Text, StyleSheet, TouchableOpacity, FlatList} from 'react-native';
import {useDispatch, useSelector} from 'react-redux';
import * as productListAction from '../store/actions/products';
import Constants from '../constants/constants';
const Products = props => {
console.log('Hello');
const token = useSelector(store => store.auth.token);
//const vendorProducts = useSelector(store => store.productList.loadedProducts);
const dispatch = useDispatch();
useEffect(() => {
async function getProductList() {
let response;
let productList;
try {
const BASEURL = Constants.BASE_URL;
response = await fetch(BASEURL + 'wp-json/wcfmmp/v1/products/', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + token,
},
});
productList = await response.json();
} catch (error) {
console.error(error);
}
dispatch(productListAction.loadedProducts(productList));
}
getProductList();
});
return (
<View>
<Text>Product</Text>
</View>
);
};
const style = StyleSheet.create({});
export default Products;

Related

Axios in React Native not calling backend server

I'm building a react native app for sign up and login. The backend works well. I checked with Postman. But the frontend doesn't call the server for the post request.
This is the Register.js
import React, { useState } from 'react';
import Axios from 'axios';
import {
StyleSheet,
SafeAreaView,
View,
Text,
TouchableOpacity,
TextInput,
} from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
export default function Register({ navigation }) {
const [nom, setNom] = useState();
const [prenom, setPrenom] = useState();
const [username, setUsername] = useState();
const [matricule, setMatricule] = useState();
const [specialite, setSpecialite] = useState();
const [email, setEmail] = useState();
const [password, setPassword] = useState();
function save() {
console.log({
"matricule": matricule,
"nom": nom,
"prenom": prenom,
"username": username,
"specialite": specialite,
"email": email,
"password": password
})
Axios.post("http://192.168.1.1:8080/api/save",{
'matricule': matricule,
'nom': nom,
'prenom': prenom,
'username': username,
'specialite': specialite,
'email': email,
'password': password
},
{
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
)
.then(res => console.log(res.data))
alert("User Registation Successfully");
navigation.replace('Login');
}
I see the alert and it navigates to another screen, and returns the data i entered correctly, but it's like it ignores the post request.
Any help would be appreciated.
Thanks
You're invoking an asynchronous operation and then, before any result has been received, immediately notifying the user that the operation succeeded (which you don't know) and immediately navigating away (which I expect could very well just abandon the asynchronous operation).
Perform these tasks in response to the asynchronous operation, not while it's still executing:
.then(res => {
console.log(res.data);
alert("User Registation Successfully");
navigation.replace('Login');
});

How to Subscribe to Platform Event Notifications with React Native

I am developing a mobile application with React Native. With this application, I connect to salesforce and make transactions.
I created Platform Events on Salesforce side and I want React Native Component to subscribe to it.
I can't use lightning/empApi or CometD because I don't code web. According to the document, my only option is Pub/Sub API.
I tried to pull it directly with FETCH but with no result.
import {View, Text} from 'react-native';
import React, { useEffect, useState } from 'react';
import { Force, oauth } from 'react-native-force';
function History() {
const [session, setSession] = useState()
const eventName = "Test_PE__e";
const replayId = -1;
const [subscription, setSubscription] = React.useState();
useEffect(() => {
oauth.getAuthCredentials(
(data) => console.log(data), // already logged in
() => {
oauth.authenticate(
() => setSession(data),
(error) => console.log('Failed to authenticate:' + error)
);
});
},[]);
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text> Subscribed to {eventName} </Text>
</View>
);
async function setPEvents(session) {
const headers = new Headers({
'Authorization': `Bearer ${session.accessToken}`,
'Content-Type': 'application/json'
});
const body = {
"event": `/event/${eventName}`,
"replayId": replayId
};
const url = `${session.instanceUrl}/services/data/v57.0/event/${eventName}/subscriptions`;
const requestOptions = {
method: 'POST',
headers: headers,
body: JSON.stringify(body)
};
const resp = await fetch(url, requestOptions)
.then(async (response) => {
console.log(response);
return await response.json();
})
.catch(error => console.log('Error:', error));
setSubscription(resp);
console.log("FIRATTT");
console.log("Result:",resp);
}
}
export default History;
What can I do to subscribe?
Or how can I use the SalesForce Pub/Sub API in React Native?

undefined is not an object evaluating '_ usecontext.user'

I am getting this error in a big react native app. Actually I am running this on expo. Can anyone see through and suggest a solution.Please Help
"undefined is not an object evaluating '_ usecontext.user'"
import React, { useState } from "react";
import { StyleSheet, Image } from "react-native";
import * as Yup from "yup";
import Screen from "../components/Screen";
import {
ErrorMessage,
Form,
FormField,
SubmitButton,
} from "../components/forms";
import authApi from "../api/auth";
import useAuth from "../auth/useAuth";
const validationSchema = Yup.object().shape({
email: Yup.string().required().email().label("Email"),
password: Yup.string().required().min(4).label("Password"),
});
function LoginScreen(props) {
const auth = useAuth();
const [loginFailed, setLoginFailed] = useState(false);
const handleSubmit = async ({ email, password }) => {
const result = await authApi.login(email, password);
if (!result.ok) return setLoginFailed(true);
setLoginFailed(false);
auth.logIn(result.data);
};
//not full code here
}
#auth.js (AuthApi) #
mport client from "./client";
const login = (email, password) => client.post("/auth", { email, password });
export default {
login,
};
#useAuth#
import { useContext } from "react";
import jwtDecode from "jwt-decode";
import AuthContext from "./context";
import authStorage from "./storage";
export default useAuth = () => {
const { user, setUser } = useContext(AuthContext);
const logIn = (authToken) => {
const user = jwtDecode(authToken);
setUser(user);
authStorage.storeToken(authToken);
};
const logOut = () => {
setUser(null);
authStorage.removeToken();
};
return { user, logIn, logOut };
};
#AuthContext#
import React from "react";
const AuthContext = React.createContext();
export default AuthContext;
Tell me if you need more code. Please Help

what should I do with "You don't have permission to access" error?

on a React-Native project I'm trying to fetch some data from an API but I end up with this error:
"error":"You don't have permission to access!"
here is my code:
import React, {useEffect} from 'react';
import {View, Text} from 'react-native';
import base64 from 'react-native-base64';
const ProductScreen = props => {
const url = 'Some_URL';
const encoded = base64.encode('user:pass');
const auth = 'Basic ' + encoded;
useEffect( () => {
fetch(url, {
method: 'POST',
'Authorization': auth,
}).then(response => response.json()).then(responseJson => {
const jsonString = JSON.stringify(responseJson);
console.log(jsonString);
});
}
);
return (
<View>
<Text>some text</Text>
</View>
);
}
export default ProductScreen;
what does this error mean? are my username and password wrong? or it means I need to get permission from the user of the app for fetching? or something else?
the problem was the 'https'. By changing it to 'http' the problem was solved.

Async call with react native and redux , thunk

I have been following this tutorial to integrate redux into my react native app.
https://github.com/jlebensold/peckish
On my Home view, I'm not able to call the functions from my action folder.
One difference is that I'm using react-navigation in my app. Wonder if I need to integrate redux with react navigation to be able to use redux for all data?
Below is the full implementation code I have been doing.
On the Home screen, I call the fetchSite function on ComponentDidMount to launch an async call with axios. But I can't even access to this function.
Sorry for this long post but I can't figure out how to make this work so quite difficult to make a shorter code sample to explain the structure of my app.
Let me know if any question.
index.ios.js
import React from 'react'
import { AppRegistry } from 'react-native'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware, compose} from 'redux'
import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger'
import reducer from './app/reducers'
import AppContainer from './app/index'
// middleware that logs actions
const loggerMiddleware = createLogger({ predicate: (getState, action) => __DEV__ });
function configureStore(initialState) {
const enhancer = compose(
applyMiddleware(
thunkMiddleware, // lets us dispatch() functions
loggerMiddleware,
),
);
return createStore(reducer, initialState, enhancer);
}
const store = configureStore({});
const App = () => (
<Provider store={store}>
<AppContainer />
</Provider>
);
AppRegistry.registerComponent('Appero', () => App;
reducers/index.js
import { combineReducers } from 'redux';
import * as sitesReducer from './sites'
export default combineReducers(Object.assign(
sitesReducer,
));
reducers/sites.js
import createReducer from '../lib/createReducer'
import * as types from '../actions/types'
export const searchedSites = createReducer({}, {
[types.SET_SEARCHED_SITES](state, action) {
let newState = {};
action.sites.forEach( (site) => {
let id = site.id;
newState[id] = Object.assign({}, site, { id });
});
return newState;
},
});
../lib/createReducer
export default function createReducer(initialState, handlers) {
return function reducer(state = initialState, action) {
if (handlers.hasOwnProperty(action.type)) {
return handlers[action.type](state, action)
} else {
return state
}
}
}
../actions/types
export const SET_SEARCHED_SITES = 'SET_SEARCHED_SITES';
AppContainer in ./app/index
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from './actions';
console.log(ActionCreators); //Properly gathered the functions from the actions folder
import { Root } from './config/router';
window.store = require('react-native-simple-store');
window.axios = require('axios');
class App extends Component {
render() {
return (
<Root />
)
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(mapDispatchToProps)(App);
ActionCreators in './actions';
import * as SiteActions from './sites'
export const ActionCreators = Object.assign({},
SiteActions,
);
Actions in './actions/sites'
import * as types from './types' //See above
export function fetchSites(token) {
return (dispatch, getState) => {
let instance = axios.create({
baseURL: url + 'api/',
timeout: 10000,
headers: {'Accept' : 'application/json', 'Authorization' : 'Bearer ' + token}
});
instance.get('/sites?page=1')
.then(response => {
console.log(response.data.data);
dispatch(setSearchedSites({sites: response.data.data}));
}).catch(error => {
console.log(error);
});
}
}
export function setSearchedSites({ sites }) {
return {
type: types.SET_SEARCHED_SITES,
sites,
}
}
Root file for navigation based on react-navigation
I made it as simple as possible for this example.
import React from 'react';
import {StackNavigator} from 'react-navigation';
import Home from '../screens/Home';
export const Root = StackNavigator({
Home: {
screen: Home,
}
});
And finally my Home screen
import React, {Component} from 'react';
import { connect } from 'react-redux';
import {Text, View} from 'react-native';
class Home extends Component {
componentDidMount()
{
let token = "12345678" //Just for this example
this.props.fetchSites(token).then( (response) => {
console.log(response);
});
}
render() {
return (
<View>
<Text>This is the Home view</text>
</View>
);
}
}
function mapStateToProps(state) {
return {
searchedSites: state.searchedSites
};
}
export default connect(mapStateToProps)(Home);
To use action methods you need to connect in home screen like this
import { fetchSites } from '<your-path>'
// your Home's other code.
const mapDispatchToProps = (dispatch) => {
return{
fetchSites:dispatch(fetchSites())
}
}
export default connect(mapStateToProps,mapDispatchToProps)(Home);
after that you can use fetchSites as this.props.fetchSites whenever you want.