how to conditionally update data field with axios - react-native

i have screen when user have buttons to change hes Name, or phone
i have function that handle if the user clicked on change name or phone
now i want to conditionally implement a PUT req, that change only the field that the user clicked,
for example look what exactly i want to do: (look at the if)
how can i do that conditinally field?
const updateUser = dispatch => async (userId, param, value, token) => {
dispatch({ type: "loading", payload: true });
try {
const res = await indexApi.put(
`/user/${userId}`,
{
if(param==="name") name: value,///////////////here
if(param==="phone")phone: value ////////////here
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
note that i also tried to do :
name: (param===name) ? value: res.data.user.name
phone: (param===phone) ? value: res.data.user.phone
I mean take the data from the server , but the server does not return me and sends me an UNDEFINED comment res.data.user.name undefined................
probably its not enough to get it until the func finish or something

if you want to do object with specified property name try this:
{
[param]: value
}
In brackets value of variable param become 'name' or 'phone' in your case.
const updateUser = dispatch => async (userId, param, value, token) => {
dispatch({ type: "loading", payload: true });
try {
const res = await indexApi.put(
`/user/${userId}`,
{
[param]: value
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);

Related

Open screen on login - react native

I have a function that shows me an alert when the username and password are correct, but I want to send me a screen as soon as the username and password are correct, I have tried but I have not been able to do it.
in my attempts I have another validation which is if I log in but it does not validate, it is only verifying that the route exists but so put the password or the wrong email log in, I need it to validate and if the user and password are correct there yes let me log in.
const signIn = async({correo, password}: LoginData) => {
try {
await fetch('https://www.portal.multigobernanza.com/apiMultigobernanza/usuarios/login.php',
{
method:'POST',
headers:{
'Accept': 'application/json',
'content-Type': 'application/json'
},
body: JSON.stringify({"email":correo, "password" : password})
}).then(res => res.json())
.then(resData => {
Alert.alert(resData.message)
console.log(resData);
});
}catch (error) {
dispatch({type: 'addError',
payload: error.response.data.msg || 'InformaciĆ³n incorrecta'})
}
};
other validation
const signIn = async({correo, password}: LoginData) => {
try {
const {data} = await cafeApi.post<LoginResponse>('/usuarios/login.php',{correo,password});
dispatch({
type: 'signUp',
payload: {
token: data.token,
user: data.usuario
}
});
await AsyncStorage.setItem('token', data.token);
} catch (error) {
dispatch({type: 'addError',
payload: error.response.data.msg || 'InformaciĆ³n incorrecta'})
}
};
GIT
https://github.com/Giovannychvz/react-native
Take a look at how react-navigation suggest authentication flows. To achieve something like that, at the very least you will need a state variable that keeps track of when a user is signed in, and to modify your signIn function to update your state variable

Vuex state is sometimes empty (undefined), especially when I refresh the page and sometimes it works

Vuex state is sometimes empty (undefined), especially when I refresh the page. And sometimes it works.
action:
getSkills(context) {
let url = "/skills";
const headers = {
"x-api-key": process.env.VUE_APP_SIRH_X_API_KEY,
Authorization: localStorage.getItem("access_token"),
};
return axios({
method: "get",
url: url,
headers: headers,
}).then((response) => {
context.commit("getSkill", response.data.data.skills);
}).catch((e) => {
console.log(e);
});
},
getter:
Skills: (state) => state.Skills,
mutation :
getSkill(state, skills) {
state.Skills = skills;
},
state :
Skills: [],
and the vue :
computed: {
...mapState({}),
...mapGetters(["Candidate", "Skills"])
},
mounted() {
this.getSkills();
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
},
methods: {
...mapActions(["attachSkillCandidate", "getSkills"]),
}
Can anyone help me to solve this issue ?
Thanks!
The getSkills action is performing an asynchronous request. You need to wait for the request to finish before you can access this.Skills otherwise the data will not be set yet.
You need async and await (the "modern" solution):
async mounted() {
await this.getSkils();
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
}
or:
mounted() {
this.getSkils().then(() => {
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
});
}

Redux Middleware, POST Request

I wrote functions for sending requests using redux api middleware. What does the POST function look like instead of GET?
RSAA getOrdersRequest(){
return RSAA(
method: 'GET',
endpoint: 'http://10.0.2.2:80/order',
types: [
LIST_ORDERS_REQUEST,
LIST_ORDERS_SUCCESS,
LIST_ORDERS_FAILURE,
],
headers: {
'Content-Type':'application/json',
},
);
}
ThunkAction<AppState> getOrders() => (Store<AppState> store) => store.dispatch(getOrdersRequest());
my function is written in dart, but the language of the example is not important,
thanks for any help
For making async calls, you should use middlewares like redux-thunk. I'll be using JavaScript here.
All you need to know about thunk is that redux-thunk allows your action creator(like postOrder) to return a function which then dispatches respective actions(object with a type and payload/data property) to the store. You can dispatch as many actions as you like.
POST is just a HTTP verb that I'm using to post an order, as you could see down here. Firstly, POST_ORDERS_REQUEST is the beginning of your request, in which, you could show loading... state or a spinner in your application. So, this action fires off, orderReducer checks what type of action has arrived, and in turn, acts accordinly and stores the data in the redux-store. I'm sure you know basic redux, so it might not be a problem for you to understand all this. The other two actions work the same way.
export const postOrder = () => {
return async (dispatch) => {
dispatch({
type: POST_ORDER_REQUEST
})
try {
const res = await axios.post("http://10.0.2.2:80/order",
{
headers: {
"Content-Type": "application/json",
}
})
dispatch({
type: POST_ORDER_SUCCESS,
data: { order: res.data.order }
})
} catch (err) {
dispatch({
type: POST_ORDER_FAILURE,
data: { error: `Order failed with an ${err}` }
})
}
}
}
You could accordingly create your orderReducer, for example:
const initialState = {
isLoading: false,
myOrder: null,
error: null
}
export const orderReducer = (state = initialState, action) => {
switch (action.type) {
case POST_ORDER_REQUEST:
return {
...state,
isLoading: true,
error: null
}
case POST_ORDER_SUCCESS:
return {
...state,
isLoading: false,
myOrder: action.data.order,
error: null
}
case POST_ORDER_FAILURE:
return {
...state,
isLoading: false,
error: action.error
}
default:
return state
}
}
You can read these good articles on Redux that you might like:
https://daveceddia.com/what-is-a-thunk/
https://daveceddia.com/where-fetch-data-redux/
since accepted response had nothing to do with redux api middleware which is made in order to reduce "boilerplatish" and repetitive thunk code, you can use createAction from redux-api-middleware like:
import { createAction } from "redux-api-middleware";
export const getOrders = () =>
createAction({
endpoint: 'http://10.0.2.2:80/orders',
method: "GET",
types: ['GET_ORDERS_PENDING', 'GET_ORDERS_SUCCESS', 'GET_ORDERS_FALED'],
});
export const getOrderById = (id) =>
createAction({
endpoint: `http://10.0.2.2:80/orders/${id}`,
method: "GET",
types: ['GET_ORDER_BY_ID_PENDING', 'GET_ORDER_BY_ID_SUCCESS', 'GET_ORDER_BY_ID_FALED'],
});
export const submitOrder = (name, price) =>
createAction({
endpoint: 'http://10.0.2.2:80/orders',
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: name,
price: price,
}),
types: ['SUBMIT_ORDER_PENDING', 'SUBMIT_ORDER_SUCCSESS', 'SUBMIT_ORDER_FAILED'],
});
in cases where you could use more handling than simple api service calling you can always combine it with thunk like this

Parameter pass from one api to another in react-native

I want to pass a parameter value from one API-Request to 2nd API-request so that 2nd api display result accordingly: Here is my function componentWillMount:
componentWillMount() {
axios.post('https://APISITE/api/Auth/AuthorizeByApplication?applicationId=b72fc47a-ef82-4cb3-8179-2113f09c50ff&applicationSecret=e727f554-7d27-4fd2-bcaf-dad3e0079821&token=cd431b31abd667bbb1e947be42077e9d')
.then((response) => { console.log(response.data); });
axios.get('https://APISITE//api/Stock/GetStockItems',
{
params: {
keyWord: 454534534543,
locationId: '',
entriesPerPage: 100000,
pageNumber: 1,
excludeComposites: true,
//add other params
},
headers:
{ Authorization: 'asdfasdsfdfdfdfsfsdxxx'
}
//}).then((response) => { console.log(response.data); });
}).then((response) => this.setState({ products: response.data }));
axios.get('https://APISITE//api/Stock/GetStockLevel', {
params: {
stockItemId: '2f80b45c-85ff-449b-9ad6-ffcc4bb640dd',
},
headers:
{ Authorization: 'asdfasdsfdfdfdfsfsdxxx'
}
// }).then(response => console.log(response));
}).then((response) => this.setState({ racks: response.data }));
}
Value in stockItemId is passed as static value and result displayed in console correctly. How can get stockItemId's value dynamically from 1st-api request?
Edit: Below is data result screenShots of passing stockItemId directly in api and getting from 1st api.
Getting from 1st api: stockItemId: stockItems.data.StockItemId : http://prntscr.com/i7k0j7
Directly passing value of stockItemId screenshot- stockItemId: '2f80b45c-85ff-449b-9ad6-ffcc4bb640dd' http://prntscr.com/i7jyq7
You need to handle the response data from within the then functions.
Notice the way the response from each request is passed into the following then where it can easily used.
componentWillMount() {
axios
.post('https://APISITE/api/Auth/AuthorizeByApplication?applicationId='app id'&applicationSecret='app secret'&token='app token'')
.then((authData) => {
console.log(authData.data);
return axios.get('https://APISITE//api/Stock/GetStockItems', {
params: {
keyWord: 5055967419551,
locationId: '',
entriesPerPage: 100000,
pageNumber: 1,
excludeComposites: true,
},
headers: {
Authorization: '0f32ae0d-c4e0-4aca-8367-0af88213d668'
}
})
})
.then((stockItems) => {
this.setState({ products: stockItems.data })
return axios.get('https://APISITE//api/Stock/GetStockLevel', {
params: {
stockItemId: stockItems.data.stockItemId,
},
headers: {
Authorization: '0f32ae0d-c4e0-4aca-8367-0af88213d668'
}
})
})
.then((stockLevel) =>
this.setState({ racks: stockLevel.data })
)
}
(This code is untested!)
First thing never use componentWillMount component life cycle method to set the component state or call any api request for these purpose use componentDidMount for more reading which life cycle use for which purpose read this article and Secondly just add the second api request inside the first api request response with different name response name as given below:
componentDidMount() {
axios.post('https://APISITE/api/Auth/AuthorizeByApplication?
applicationId='app id'&applicationSecret='app secret'&token='app token'')
.then((responseFirst) => {
axios.get('https://APISITE//api/Stock/GetStockItems', {
params: {
keyWord: 5055967419551,
locationId: '',
entriesPerPage: 100000,
pageNumber: 1,
excludeComposites: true,
},
headers: {
Authorization: '0f32ae0d-c4e0-4aca-8367-0af88213d668'
}
}).then((responseSecond) => this.setState({ products: responseSecond.data }));
axios.get('https://APISITE//api/Stock/GetStockLevel', {
params: {
stockItemId: responseFirst.data.stockItemId,
},
headers: {
Authorization: '0f32ae0d-c4e0-4aca-8367-0af88213d668'
}
}).then((responseThird) => this.setState({ racks: responseThird.data }));
});
}
if you are using redux then read redux documentation to handle async type actions and how to handle it.

Vuex - passing multiple parameters to mutation

I am trying to authenticate a user using vuejs and laravel's passport.I am not able to figure out how to send multiple parameters to the vuex mutation via an action.
- store -
export default new Vuex.Store({
state: {
isAuth: !!localStorage.getItem('token')
},
getters: {
isLoggedIn(state) {
return state.isAuth
}
},
mutations: {
authenticate(token, expiration) {
localStorage.setItem('token', token)
localStorage.setItem('expiration', expiration)
}
},
actions: {
authenticate: ({
commit
}, token, expiration) => commit('authenticate', token, expiration)
}
})
- login method -
login() {
var data = {
client_id: 2,
client_secret: '**************************',
grant_type: 'password',
username: this.email,
password: this.password
}
// send data
this.$http.post('oauth/token', data)
.then(response => {
// send the parameters to the action
this.$store.dispatch({
type: 'authenticate',
token: response.body.access_token,
expiration: response.body.expires_in + Date.now()
})
})
}
I would be very thankful for any kind of help!
Mutations expect two arguments: state and payload, where the current state of the store is passed by Vuex itself as the first argument and the second argument holds any parameters you need to pass.
The easiest way to pass a number of parameters is to destruct them:
mutations: {
authenticate(state, { token, expiration }) {
localStorage.setItem('token', token);
localStorage.setItem('expiration', expiration);
}
}
Then later on in your actions you can simply
store.commit('authenticate', {
token,
expiration,
});
In simple terms you need to build your payload into a key array
payload = {'key1': 'value1', 'key2': 'value2'}
Then send the payload directly to the action
this.$store.dispatch('yourAction', payload)
No change in your action
yourAction: ({commit}, payload) => {
commit('YOUR_MUTATION', payload )
},
In your mutation call the values with the key
'YOUR_MUTATION' (state, payload ){
state.state1 = payload.key1
state.state2 = payload.key2
},
i think this can be as simple
let as assume that you are going to pass multiple parameters to you action as you read up there actions accept only two parameters context and payload which is your data you want to pass in action so let take an example
Setting up Action
instead of
actions: {
authenticate: ({ commit }, token, expiration) => commit('authenticate', token, expiration)
}
do
actions: {
authenticate: ({ commit }, {token, expiration}) => commit('authenticate', token, expiration)
}
Calling (dispatching) Action
instead of
this.$store.dispatch({
type: 'authenticate',
token: response.body.access_token,
expiration: response.body.expires_in + Date.now()
})
do
this.$store.dispatch('authenticate',{
token: response.body.access_token,
expiration: response.body.expires_in + Date.now()
})
hope this gonna help