Pass Array/Object as parameter in Axios React native - react-native

I want to pass parameter in POST request in Axios library as :
{
params :
{
email: email,
password: password,
}
}
I have tried :
axios.post(url,
{
params : {
email: 'a#aa.com',
password: 'Password!',
sign_in_type: '1',
fb_token: '',
google_token: ''
}
},
{headers: headers}
)
But nothing works! Please suggest if you have any idea.
Thank you!

const getData = async () => {
const params = {
params: {
email: 'something#somelthing.com',
.....
}
};
try {
const { data } = await axios({
method: 'post',
url: `your url`,
data: params,
headers: {
'token': token
}
});
console.log(data);
} catch(e) {
console.log(e);
}
}

Related

React Native: setState doesn't work when calling try-catch function

I tried to call APP with this code imported from another file and it worked fine:
import FormData from 'FormData';
import AsyncStorage from '#react-native-community/async-storage';
let formData = new FormData();
formData.append('userId', '1'); // < this is what I want to change
formData.append('key', '***'); //my key
export function getScoreFromAPI () {
return fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
method : 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body : formData
} )
.then((response) => {
return response.json()
})
.catch((error) => console.log("l'erreure est: " + error))
}
but now I want to change my userId from 1 to an constante from Asyncstorage, so I decide to change my code to this:
constructor(props) {
super(props)
this.state = { infos: [], userId: '' }
}
componentWillMount() {
this.getScoreFromAPI().then(data => {
this.setState({ infos: data })
});
console.log(this.state.infos);
AsyncStorage.getItem(USERID_STORED)
.then((data) => {
if (data) {
this.setState({userId:data})
}
});
}
async getScoreFromAPI() {
let formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //my key
try {
let response = await fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
let res = await response.json();
} catch(error) {
console.warn("errors are " + error);
}
};
with a try-catch function but when I call getScoreFromAPI() in ComponentWillMount() I can't setState with received data, I still have an empty array in info:[]
my questions:
how can I replace '1' in userId by a value in asyncstorage in the first file ?
if it isn't possible, what I have do to setState info: [] with my data reveived
I've simplified your code into a promise chain in which calling getScoreFromAPI will execute after getting the userId from AsyncStorage, then storing the response into the infos state, while returning null if there was an error, and logging the error to the console. The data was not previously returned from getScoreFromAPI, so the value would always become null. I have not tested this code, but this should give you a good base to work from:
import FormData from 'FormData';
import AsyncStorage from '#react-native-community/async-storage';
export default class Test {
constructor() {
this.state = {
infos: null,
userId: ''
};
}
componentDidMount() {
AsyncStorage.getItem(this.state.userId)
.then(userID => {
this.setState({ userId: userID || '' });
})
.then(() => {
return this.getScoreFromAPI();
})
.then(data => {
this.setState({ infos: data });
})
.catch(console.error);
}
getScoreFromAPI = () => {
const formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //my key
fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
.then(response => {
// use response data here
return response.json();
})
.catch(e => {
console.error(e);
return null;
});
};
}
You're doing your API call before fetching your value from AsyncStorage (I know this is async but it's not very readable if you do it that way).
getScoreFromAPI doesn't return anything, that's why your setState isn't working.
You don't need to use try and catch here, promises have their own error handling mechanism (the .catch() method).
I think callbacks are more readable and lead to less bugs than using .then() in code.
This is how I would do it:
constructor(props)
{
super(props);
this.state = { infos: [], userId: '' };
this.onSuccess = this.onSuccess.bind(this);
this.onFailure = this.onFailure.bind(this);
}
componentWillMount()
{
// Get userID from local storage, then call your API
AsyncStorage.getItem(YOUR_KEY)
.then(userID=> {
if (userID)
{
this.setState({ userId : userID }, () => {
this.getScoreFromAPI(this.onSuccess, this.onFailure);
});
}
});
}
onSuccess(data)
{
this.setState({
infos : data
});
}
onFailure(err)
{
console.warn('Error ' + err);
}
getScoreFromAPI(onSuccess, onFailure)
{
let formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //your key
fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
method : 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
.then(res => res.json())
.then(json => {
onSuccess(json);
})
.catch(err => {
onFailure(err);
});
}
It's finally done. I tried this and it worked. Thank you to all of you
this is what I have done:
...
const USERID_STORED = "userid_stored";
const GSM_STORED = "gsm_stored";
...
class ScoreList extends React.Component {
constructor(props) {
super(props)
this.state = { infos: [], userId: '', gsmStored: '', }
}
componentWillMount() {
AsyncStorage.getItem(USERID_STORED)
.then(userId => {
this.setState({ userId: userId});
this.getScoreFromAPI(this.state.userId).then(data => {
this.setState({ infos: data });
});
});
AsyncStorage.getItem(GSM_STORED)
.then(gsmStore => {
this.setState({ gsmStored: gsmStore});
});
}
getScoreFromAPI (userId) {
let formData = new FormData();
formData.append('userId', userId);
formData.append('key', '***');
return fetch('https://***',{
method : 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body : formData
} )
.then((response) => {
return response.json()
})
.catch((error) => console.log("l'erreure est: " + error))
};

How to upload image in react-native using axios?

I am trying to upload Image with Axios but getting: Request failed with status code 500.I don't have backend problem because I can upload image with postman and everything is fine.
This is my addDocument() in FileUpload.js.
addDocument(){
let { title, description, imgUri } = this.state;
console.log(this.state.imgUri);
const body = new FormData();
body.append('image', {
uri: imgUri,
type: 'image',
name : `${new Date().getTime()}.jpg`,
});
addDocument(title, description, body).then((response) => {
if (response.isSuccess == true) {
this.setState({ loading: false });
this.props.navigation.navigate('FileList',{isUpdate:'true'});
}
});
};
This is my addDocument() in document.service.js.
export const addDocument = async (title, description, imageFile) => {
const trekkerId = await AsyncStorage.getItem("trekker_id");
const model = {
profileDocumentId: '',
title: title,
description: description
}
console.log(model);
console.log(imageFile);
if (trekkerId) {
return axios({
method: 'post',
url: baseUrl + "/api/Document/Document",
data: {
file: imageFile,
model: model
},
headers: {
'profileId': trekkerId,
'Authorization': 'Bearer ' + await AsyncStorage.getItem("id_token"),
'Content-Type': 'multipart/form-data'
},
}).then((response) => {
// console.log(response);
return {
isSuccess: true
};
}).catch((error) => {
console.log(error);
return {
isSuccess: false,
}
});

Redux async actioncreator not recognizing then

I need to use .then() on a redux action, what is wrong in the following action?
export const userLogin = (username, password) => {
return dispatch => {
axios.post(`${TT_API_BASE}/Access/Login`, { username: username, password: password, applicationId: 2 }, {
headers: {
'Content-Type': 'application/json;charset=utf-8',
'Authorization': 'Basic ' + auth,
}
})
.then(response => {
dispatch({
type: LOGIN,
payload: response.data
})
})
.catch(err => {
console.log(err)
dispatch({
type: LOGIN_FAILED
})
})
}
}
It is then called in a component like this
handlePress() {
this.props.userLogin(this.state.username, this.state.password)
.then(() => {
this.props.navigation.navigate('SelectInstance')
})
}
Which displays the errormessage that then is not defined. What am I doing wrong?
When you do dispatch(someThunkActionCreator()), the return value of dispatch is whatever your thunk function returns. So, you can only do dispatch().then() if the thunk function returns a promise.
Your thunk is making an AJAX call, but not actually returning a promise, so it actually returns undefined. Putting a return statement in front of axios.post() will return that promise and fix the problem.
Solved by doing this:
export const userLogin = (username, password) => {
return async dispatch => {
const onSuccess = data => {
dispatch({
type: LOGIN,
payload: data
})
}
const onError = err => {
dispatch({
type: LOGIN_FAILED
})
}
try {
const req = await axios.post(`${TT_API_BASE}/Access/Login`, { username: username, password: password, applicationId: 2 }, {
headers: {
'Content-Type': 'application/json;charset=utf-8',
'Authorization': 'Basic ' + auth,
}
})
return onSuccess(req.data)
}
catch (err) {
return onError(err)
}
}
}

how can we get post data from fetch function in react native to express api?

Question:
How can we get post data from fetch function in react native to express api?
Issue Faced:
I tried the following process but didn't got those variables in back-end API.
How can the variables be achieved in the backend API? Any suggestions are highly appreciated.
Here is the reactive native fetch function:
REACT NATIVE FETCH FUNCTION:
login = async () => {
await fetch('http://192.168.1.160:8001/api/login', {
method: 'POST',
mode: 'cors',
cache: 'default',
header: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: this.state.email,
password: this.state.password
})
})
.then ((response) => response.json())
.then ((res) => {//console.log(res);
if(res.error === false){
AsyncStorage.setItem('user', res.data);
this.props.navigation.navigate('profile');
} else{
// alert(res.message);
}
})
}
Express-API:
The express API is given below:
module.exports = function (req, res) {
console.log('TEST',req.body);
let { email, password } = req.body;
let input = { email, password };
const validator = loginValidator(input);
if (validator.error) {
return res.status(400).json({
error: true,
message: validator.error.details,
});
} else {
models.users.findOne({
where: { email: email }
}).then(user => {
if (!user) {
return res.status(400).json({
error: true,
message: {
key: 'email',
text: MessageHelper.email_already_exist
}
});
} else if (!bcrypt.compareSync(password, user.password)) {
return res.status(400).json({
error: true,
message: {
key: 'password',
text: MessageHelper.password_not_valid
}
});
} else {
var token = jwt.sign({ userid: user.id },Config.get('jwt.privatekey'));
models.users.update({ token: token },{ where: { id: user.id } }).then(function(result){
return res.json({
error: false,
message: MessageHelper.user_token_updated,
token: token,
data: {
user_id: user.id,
firstname: user.firstname,
lastname: user.lastname,
username:user.username,
email: user.email,
mobile: user.mobile,
token: user.token
}
});
}).catch(function(error){
return res.status(400).json({
error: true,
message: error
});
})
}
});
}
}
Fetch also takes an optional second argument that allows you to
customize the HTTP request. You may want to specify additional
headers, or make a POST request:
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
}),
});
Networking is an inherently asynchronous operation. Fetch methods will
return a Promise that makes it straightforward to write code that
works in an asynchronous manner:
function getMoviesFromApiAsync() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
}

Hapi Lab how to test all the required fields

Is there a way to check all the required fields
without the need of a test each field.
validation rules
const Confirmation = Joi.any().valid(Joi.ref('password')).required().options({ language: { any: { allowOnly: 'must match password' } } });
const Email = Joi.string().email();
const Firstname = Joi.string().regex(/^[a-zA-Z\']+$/).min(2).max(30);
const Lastname = Joi.string().regex(/^[a-zA-Z\']+$/).min(2).max(30);
const Password = Joi.string().min(3).max(30);
const Username = Joi.string().regex(/^[a-zA-Z\-\.]+$/).min(3).max(30);
exports.create = {
payload: {
email: Email.required(),
firstname: Firstname.required(),
lastname: Lastname.required(),
password: Password.required(),
password_confirmation: Confirmation,
username: Username.required()
}
};
test
'use strict';
const Lab = require('lab');
const lab = exports.lab = Lab.script();
const Code = require('code');
const Server = require('../../index');
lab.experiment('User', function() {
lab.test('create firstname should be required', function (done) {
const options = {
method: 'POST',
url: '/api/users',
payload: {
email: 'me#mydomain.com',
password: 'mysecret'
}
};
Server.inject(options, function(response) {
const result = response.result;
Code.expect(response.statusCode).to.equal(422);
Code.expect(result.message).to.equal('child "firstname" fails because ["firstname" is required]');
done();
});
});
//AND SO ON
lab.test('create firstname should be required', function (done) {
const options = {
method: 'POST',
url: '/api/users',
payload: {
email: 'me#mydomain.com',
password: 'mysecret',
firstname: 'me'
}
};
Server.inject(options, function(response) {
const result = response.result;
Code.expect(response.statusCode).to.equal(422);
Code.expect(result.message).to.equal('child "lastname" fails because ["lastname" is required]');
done();
});
});
});
The answer from #simon-p-r would be a possible solution. But I do not understand why you want to validate the Joi Schemas by checking each required field with a test in the first place. As far as I can tell Joi has a test-coverage of 100% and can be considered thoroughly tested - so why do that again?
I would just test the success and failure case as well as some edge cases (like confirmation of password missing, wrong, etc.)...
'use strict';
const Lab = require('lab');
const lab = exports.lab = Lab.script();
const Code = require('code');
const Server = require('../../index');
lab.experiment('User', function() {
//Failure case
lab.test('create should fail if required fields are missing', function(done) {
const options = {
method: 'POST',
url: '/api/users',
payload: {
email: 'me#mydomain.com',
firstname: 'foo',
lastname: 'bar'
}
};
Server.inject(options, function(response) {
Code.expect(response.statusCode).to.equal(400);
done();
});
});
//Success case
lab.test('create should succeed if all fields are valid', function(done) {
const options = {
method: 'POST',
url: '/api/users',
payload: {
email: 'me#mydomain.com',
firstname: 'foo',
lastname: 'bar',
password: 'secret',
password_confirmation: 'secret',
username: 'foo.bar'
}
};
Server.inject(options, function(response) {
Code.expect(response.statusCode).to.equal(200);
//maybe do some more checks on the response here...
done();
});
});
//Edge cases
lab.test('create should succeed if all fields are valid', function(done) {
const options = {
method: 'POST',
url: '/api/users',
payload: {
email: 'me#mydomain.com',
firstname: 'foo',
lastname: 'bar',
password: 'secret',
password_confirmation: 'something_else',
username: 'foo.bar'
}
};
Server.inject(options, function(response) {
Code.expect(response.statusCode).to.equal(400);
//maybe do some more checks on the response here...
done();
});
});
//And so on...
});
I hope this helps.
If you want to test all the field's validation you may want to set abortEarly to false in the options of validate method. If you are using built-in validation via route config set options object like so
{
method: 'POST',
path: '/api/users',
config: {
handler: handlerFunc,
validate: {
payload: Joi.schema(),
options: {
abortEarly: false
}
}
}
},
This should catch all errors.