I'm trying to take some action after upload completion of multiple images, using Promise.all.
However, the code after then runs before the code being dispatched.
What am I confusing here?
submit_all_images({ dispatch, rootState }) {
const imageFileArray = rootState.imageStore.imageFileArray
var promiseArray = []
for ( var imageFile of imageFileArray ) {
promiseArray.push(dispatch('get_signed_request', imageFile))
}
Promise.all(promiseArray)
.then(results => {
console.log("finished with results: " + results)
return dispatch('submit_entire_form')
});
},
get_signed_request ({ dispatch, commit, state }, imgFile) {
const requestObject = {imageName: imgFile.name, imageType: `${imgFile.type}`}
axios.post('http://localhost:3000/sign-s3', requestObject)
.then(response => {
if (response.body.signedRequest && response.body.awsImageUrl) {
const signedRequest = response.body.signedRequest
const awsImageUrl = response.body.awsImageUrl
dispatch('upload_file', { imgFile, signedRequest, awsImageUrl })
} else {
alert('Could not get signed URL.');
}
}, error => {
console.log("ERROR: " + error)
})
},
upload_file ({ dispatch, commit, state}, { imgFile, signedRequest, awsImageUrl }) {
axios.put(signedRequest, imgFile, {
headers: {'Content-Type': imgFile.type}
}).then(response => {
console.log('finished uploading file: ' + imgFile.name )
commit(types.UPDATE_LICENSE_IMG_URLS, awsImageUrl)
}, error => {
alert("fail")
console.log(error)
})
},
I'm not entirely sure, since I have no experience with vuex, but I guess you're missing a few return statements.
get_signed_request({ dispatch, commit, state }, imgFile){
const requestObject = {imageName: imgFile.name, imageType: `${imgFile.type}`}
//here
return axios.post('http://localhost:3000/sign-s3', requestObject)
.then(response => {
if (response.body.signedRequest && response.body.awsImageUrl) {
const signedRequest = response.body.signedRequest
const awsImageUrl = response.body.awsImageUrl
//here
return dispatch('upload_file', { imgFile, signedRequest, awsImageUrl })
} else {
alert('Could not get signed URL.');
}
}, error => {
console.log("ERROR: " + error)
})
},
upload_file({ dispatch, commit, state}, { imgFile, signedRequest, awsImageUrl }){
//here
return axios.put(signedRequest, imgFile, {
headers: {'Content-Type': imgFile.type}
}).then(response => {
console.log('finished uploading file: ' + imgFile.name )
//and here
return commit(types.UPDATE_LICENSE_IMG_URLS, awsImageUrl)
}, error => {
alert("fail")
console.log(error)
})
},
So that get_signed_request returns a Promise that resolves only after axios.post().then() is done, wich depends on first resolving dispatch('upload_file', ...)
And the same for upload_file depending on resolving axios.put().then()depending on commit(types.UPDATE_LICENSE_IMG_URLS, awsImageUrl)
Related
how to write a method to return async storage value in react native.
I have done login authentication using Context API.
AuthContext.js
import React, { createContext } from "react";
import { useState, useEffect } from "react";
import { Alert } from "react-native";
import AsyncStorage from '#react-native-async-storage/async-storage';
import NetInfo from "#react-native-community/netinfo";
import { BASE_URL } from "../constants/Const";
export const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
// loading & usertoken hooks
const [isLoading, setIsLoading] = useState(false);
const [userToken, setuserToken] = useState(null);
//login method
const login = async (email, password) => {
setIsLoading(true);
//fetch method to get access token
fetch(`${BASE_URL}/sign_in`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password,
})
})
.then((res) => res.json())
.then((json) => {
//console.log("login auth ", json)
if (json.responseCode == 200) {
try {
setuserToken(json.responseData.access_token);
//storing usertoken value in react-native encrypted storage
AsyncStorage.setItem("userToken", json.responseData.access_token)
//console.log("user token",userToken);
}
catch (error) {
console.log("Error while saving user token data", userToken);
}
}
//showing invalid email & password alert messaqge
else {
Alert.alert('Invalid email or password.');
return;
}
})
.catch((error) => {
console.error(error);
});
setIsLoading(false);
}
//logout method
const logout = async () => {
setIsLoading(true);
//setting user token as null
setuserToken(null);
try {
//removing usertoken value in react-native encrypted storage
await AsyncStorage.removeItem("userToken");
} catch (error) {
// There was an error on the native side
console.log("Error while removing data", error);
}
setIsLoading(false);
}
// checking user is already logged in each time when app starts
const isLoggenIn = async () => {
try {
setIsLoading(true);
//let userToken = await EncryptedStorage.getItem("userToken");
let userToken = await AsyncStorage.getItem("userToken");
//console.log("accesed user token",userToken);
setuserToken(userToken);
setIsLoading(false);
} catch (error) {
console.log("Error retrieving data", error);
}
}
const [connected, setConnected] = useState(true);
useEffect(() => {
isLoggenIn();
// Subscribe
const unsubscribe = NetInfo.addEventListener(state => {
// console.log("Connection type", state.type);
// console.log("Is connected?", state.isConnected);
setConnected(state.isConnected);
});
//clean up function
return () => unsubscribe();
}, [])
return (
<AuthContext.Provider value={{ login, logout, isLoading, userToken ,connected,}}>
{children}
</AuthContext.Provider>
)
}
in Redux slice file I want access token values to make a fetch request to a server.i defined getAccessToken Method to return accessToken value but it is not returning value
DataSlice.js
import { createSlice, createAsyncThunk } from '#reduxjs/toolkit'
import { useState } from 'react';
import { Alert } from 'react-native';
import { BASE_URL } from '../constants/Const';
import AsyncStorage from '#react-native-async-storage/async-storage';
//const accessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiNjM2YTFlNTc4YWNlNTRjM2E5OWE4YWI2IiwiZW1haWwiOiJhZG1pbkBnbWFpbC5jb20iLCJpYXQiOjE2Njg0MDY2MzgsImV4cCI6MTY2ODQ2MDYzOH0.i_GHy2K91I0_159AIpQ4m2eFUmyXYFmF3_0sQ-o_x-w";
//user token function
const getAcessToken = async () => {
const token = await AsyncStorage.getItem('userToken');
return token;
}
var userToken = getAcessToken();
// get and delete method request options
const getDeleteRequestOptions = (methodType) => {
return {
method: methodType,
headers: {
'Content-Type': 'application/json',
'autherization': userToken
}
}
}
// save and edit method request options
const saveEditRequestOptions = (methodType, data) => {
console.log("img uri",data.imgUri)
const imgData = new FormData();
imgData.append('first_name', data.firstName);
imgData.append('last_name', data.lastName);
imgData.append('phone', data.phoneNo);
imgData.append('email', data.email);
imgData.append('image', { uri: data.imgUri, name: 'image', type: 'image/jpg' });
return {
method: methodType,
headers: {
'Content-Type': 'multipart/form-data',
'autherization': userToken
},
body: imgData
}
};
// fetch data
export const getData = createAsyncThunk('fetch', async ({pageNo,limit}) => {
return fetch(`${BASE_URL}/list_profile?page_number=${pageNo}&limit=${limit}`, getDeleteRequestOptions('GET'))
.then((response) => response.json())
.then((json) => {
//returning json receive array
if(pageNo === 0 && limit === 0){
return {data:json.receive,fetchAllData:true};
}
return {data:json.receive,fetchAllData:false};
})
.catch((error) => {
console.error(error);
});
});
// delete data
export const deleteData = createAsyncThunk('delete', async ({id}) => {
return fetch(`${BASE_URL}/delete_profile/${id}`, getDeleteRequestOptions('DELETE',userToken))
.then((res) => res.json())
.catch((error) => {
console.error(error);
});
});
// save data
export const saveData = createAsyncThunk('save', async (data) => {
return fetch(`${BASE_URL}/add_profile`, saveEditRequestOptions('POST', data))
.then((res) => res.json())
.then((json) => {
if (json.responseCode === 211) {
Alert.alert('Input Error', json.responseMessage, [
{ text: "OK" }
])
return;
}
console.log("save responese message ", json.responseMessage);
})
.catch((error) => {
console.error(error);
});
});
// edit data
export const editData = createAsyncThunk('edit', async (data) => {
return fetch(`${BASE_URL}/update_profile/${data.id}`, saveEditRequestOptions('PUT', data))
.then((res) => res.json())
.then((json) => {
console.log("edit data response message ", json.responseMessage);
})
.catch((error) => {
console.error(error);
});
});
const initialState = {
masterData: [],
filteredData: [], //array to implement search
allData:[],
imgurl: '',
};
export const dataSlice = createSlice({
name: 'crud',
initialState,
reducers: {
filterData: (state, action) => {
state.filteredData = action.payload;
},
selectedImage: (state, action) => {
state.imgurl = action.payload;
},
},
extraReducers: {
// get data
[getData.pending]: (state, action) => {
console.log('fetching data is pending');
},
[getData.fulfilled]: (state, action) => {
console.log('data fetched successfully')
if (!action.payload) {
Alert.alert('Network error', 'Data Fetching is Failded Please try Again later.', [
{ text: "OK" }
])
return;
}
console.log(action.payload.fetchAllData)
if(action.payload.fetchAllData){
//console.log("inside fetch all data")
state.allData = action.payload.data;
}
state.masterData = action.payload.data;
state.filteredData = action.payload.data;
},
[getData.rejected]: (state, action) => {
console.log('fetching request rejected');
},
// delete data
[deleteData.pending]: (state, action) => {
console.log('delete data is pending');
},
[deleteData.fulfilled]: (state, action) => {
console.log('data deleted successfully');
},
[deleteData.rejected]: (state, action) => {
console.log('data delete request rejected');
Alert.alert('Delete Data Failure', 'Deleting Data Failed. Please try Again later.', [
{ text: "OK" }
])
},
// save data
[saveData.pending]: (state, action) => {
console.log('saving data is pending');
},
[saveData.fulfilled]: (state, action) => {
console.log('data saved successfully');
},
[saveData.rejected]: (state, action) => {
console.log('data save request rejected');
Alert.alert('Data Save Failure', 'Data Save Failed. Please try Again later.', [
{ text: "OK" }
])
},
//edit data
[editData.pending]: (state, action) => {
console.log('edit data is pending');
},
[editData.fulfilled]: (state, action) => {
console.log('data edited successfully');
},
[editData.rejected]: (state, action) => {
console.log('edit data request rejected');
Alert.alert('Data Edit Failure', 'Edit data Failed. Please try Again later.', [
{ text: "OK" }
])
},
},
})
// Action creators are generated for each case reducer function
export const { filterData, selectedImage } = dataSlice.actions;
export default dataSlice.reducer
i want to get access token values
The reason is that you are not calling getAccessToken() with await like this:
var userToken = await getAcessToken();
since it is asynchronous function.
So, I'm trying to fetch base64 data (urls) from two images I uploaded to the cloud/server, but when I parsed the response, I only get 1 object instead of 2 (i.e. only the url for the first image).
I must be overseeing something fundamentally, but I can't see it. Appreciate the advice.
Can some help explain to me why the code below doesn't work?
[EDIT: I've included the server code. Hopefully this makes it clearer as to the problem I'm facing]
.then(token => {
authToken = token;
return fetch("myappURL/storeImage",
{
method: "POST",
body: JSON.stringify({
image: image.base64,
coverImage: coverImage.base64
}),
headers: { Authorization: "Bearer " + authToken }
});
})
.catch(err => {
console.log(err);
alert("Oops! Something went wrong, please try again1")
dispatch(uiStopLoading());
})
.then(res => {
if (res.ok) {
return res.json();
} else {
throw(new Error());
}
})
.then(parsedRes => {console.log(parsedRes)}); // I only get 1 result instead of 2 (why?!)
Server-side code:
exports.storeImage = functions.https.onRequest((request, response) => {
return cors(request, response, () => {....
.then(decodedToken => {
const body = JSON.parse(request.body);
fs.writeFileSync("/tmp/uploaded-image.jpg", body.image, "base64", err => {
console.log(err);
return response.status(500).json({ error: err });
});
const bucket = gcs.bucket("myapp.appspot.com");
const uuid = UUID();
return bucket.upload(
"/tmp/uploaded-image.jpg",
{
uploadType: "media",
destination: "/places/" + uuid + ".jpg",
metadata: {
metadata: {
contentType: "image/jpeg",
firebaseStorageDownloadTokens: uuid
}
}
},
(err, file) => {
if (!err) {
return response.status(201).json({ // I get this returned
imageUrl:
"https://firebasestorage.googleapis.com/v0/b/" +
bucket.name +
"/o/" +
encodeURIComponent(file.name) +
"?alt=media&token=" +
uuid,
imagePath: "/places/" + uuid + ".jpg"
});
} else {
console.log(err);
return response.status(500).json({ error: err });
}
}
);
})
.catch(error => {
console.log("Token is invalid!");
response.status(403).json({error: "Unauthorized"});
})
.then(decodedToken => {
const body = JSON.parse(request.body);
fs.writeFileSync("/tmp/uploaded-coverImage.jpg", body.coverImage, "base64", err => {
console.log(err);
return response.status(500).json({ error: err });
});
const bucket = gcs.bucket("myapp.appspot.com");
const uuid = UUID();
return bucket.upload(
"/tmp/uploaded-coverImage.jpg",
{
uploadType: "media",
destination: "/coverPlaces/" + uuid + ".jpg",
metadata: {
metadata: {
contentType: "coverImage/jpeg",
firebaseStorageDownloadTokens: uuid
}
}
},
(err, coverFile) => {
if (!err) {
return response.status(201).json({ // I do NOT get this returned (why not?!)
coverImageUrl:
"https://firebasestorage.googleapis.com/v0/b/" +
bucket.name +
"/o/" +
encodeURIComponent(coverFile.name) +
"?alt=media&token=" +
uuid,
coverImagePath: "/coverPlaces/" + uuid + ".jpg"
});
} else {
console.log(err);
return response.status(500).json({ error: err });
}
}
);
})
.catch(error => {
console.log("Token is invalid!");
response.status(403).json({error: "Unauthorized"});
});
});
});
I'm developing a ReactJS app.
I'm getting the following error "TypeError: undefined is not an object (evaluating '_this.props.auth(values.username, values.password).then')".
When the "return new Promise" is outside the "then" it works properly. Nonetheless, I want to return the promise after only the two first "then"s.
Sample of loginActions.js
export const auth = (username, password) => dispatch => {
fetch('http://localhost/webservices/login', {
method: 'post',
body: JSON.stringify({ username, password })
})
.then(res => {
if(res.ok) {
console.log("Succeeded.", res);
return res.json();
} else {
console.log("Failed.", res);
return res.json();
}
})
.then(json => {
if (json.token) {
auth_status.value = true;
return auth_status.value;
} else {
auth_status.value = false;
return auth_status.value;
}
})
.then(function(res){
return new Promise((resolve, reject) => {
dispatch({
type: VERIFY_AUTH,
payload: res
});
resolve();
})
})
.catch(err => {
console.error(err);
});
};
Sample of login.js
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log("Received values of form: ", values);
this.props.auth(values.username, values.password).then(() => {
if (this.props.auth_status === true) {
message.success("Welcome!", 3);
this.setState({
redirect: true
});
} else {
message.error("The username and password combination is incorrect", 3);
}
})
.catch(err => {
console.error(err);
});
}
});
};
Your action auth is not returning anything. The return statements in the asynchronous handlers do not return for the action itself.
You need to return a Promise in your auth() action that you resolve yourself in the third then:
export const auth = (username, password) => dispatch => {
// instantly return a new promise that
// can be resolved/rejected in one of the handlers
return new Promise((resolve, reject) => {
fetch('http://localhost/webservices/login', {
method: 'post',
body: JSON.stringify({
username,
password
})
}).then(res => {
if (res.ok) return res.json();
// your probably also want to reject here
// to handle the failing of the action
reject();
}).then(json => {
if (json.token) {
auth_status.value = true;
return auth_status.value;
} else {
auth_status.value = false;
return auth_status.value;
}
}).then(res => {
dispatch({
type: VERIFY_AUTH,
payload: res
});
// resolve the original promise here
resolve();
}).catch(err => console.error(err));
});
};
i am having exsiting service to make api call through axios in my react app,which i think is limited to one api request at a time,i wanted to make multiple request using axios.all,but i am not able to find way to modify the service,see below is the code
As in Action.js you can see that i combine two request which is wrong i guess so,please help me how to combine two request using axios.all,and please suggest api service implementation is correct or what can i do to improve it
APIService.js
import axios from 'axios';
import apiConfig from './apiConfig';
import UserSession from './userSession';
import history from '../utils/history/history';
const session = sessionStorage;
var axiosConfig = axios.create({
baseURL: apiConfig.baseUrl,
headers: {
Authorization: sessionStorage.getItem('token') != null ?
`Bearer ${sessionStorage.getItem('token')}` : null,
Accept: 'application/json',
'Content-Type': 'application/json'
},
timeout: 20000,
responseType: 'json'
});
axiosConfig.interceptors.request.use((config) => {
config.headers.Authorization =
sessionStorage.getItem('token') != null ? `Bearer
${sessionStorage.getItem('token')}` : null;
return config;
},(error) => Promise.reject(error));
const apiService = function(options) {
const onSuccess = function(response) {
if (response.status === 201) {
return Promise.resolve(
Object.assign(
{},
{
message: response.statusText
}
)
);
} else if (response.status === 200) {
if ((response.data && response.data !== null) || response.data !==
undefined || response.data !== '') {
return response.data;
} else {
return Promise.resolve(
Object.assign(
{},
{
message: response.statusText
}
)
);
}
} else if (response.data.length < 1) {
return Promise.reject(
Object.assign(
{},
{
message: 'No Data'
}
)
);
} else {
return response.data;
}
};
const onError = function(error) {
if (error.response) {
if (error.response.status === 401) {
sessionStorage.removeItem('token');
window.location = '/login';
return Promise.reject(error.response);
} else if (error.response.status === 404) {
return Promise.reject(
Object.assign(
{},
{
message: error.response.statusText
}
)
);
} else if (error.response.status === 500) {
return Promise.reject(
Object.assign(
{},
{
message: error.response.statusText
}
)
);
} else {
return Promise.reject(error.response.data);
}
} else if (error.request) {
// The request was made but no response was received
return Promise.reject(
Object.assign(
{},
{
message: error.message
}
)
);
//return Promise.reject(error.message);
} else {
// Something else happened while setting up the request
// triggered the error
return Promise.reject(
Object.assign(
{},
{
message: error.message
}
)
);
}
};
return axiosConfig(options).then(onSuccess).catch(onError);
};
export default apiService;
Request.js
import apiService from '../apiService';
export const FirstRequest = () => {
return apiService({
url: 'FirstURL',
method: 'get',
});
};
export const SecondRequest = () => {
return apiService({
url: 'SecondURL',
method: 'get',
});
};
Action.js
export const SomeHandler = () => (dispatch) => {
dispatch({
type: API_REQUEST
});
FirstRequest()
.then((res) => {
dispatch({
type: API_SUCCESS
});
SecondRequest().then((res) => {
dispatch({
type: API_SUCCESS
});
dispatch({ type: VIEW1, payload: res });
dispatch({ type: VIEW2, payload: res });
}).catch((err) => {
dispatch({
type: API_FAILURE,
payload: err
});
});
})
.catch((err) => {
dispatch({
type: API_FAILURE,
payload: err
});
});
};
This is not related to axios at all. You can combine two async functions together in an action method, using async library:
async.parallel([
getUsers,
getComments
],
function(err, results) {
// the results array will equal to [[], {'x': 'y'}] even though
// the second function had a shorter timeout.
// dispatch here
});
function getUsers(callback) {
callback(null, [])
}
function getComments(callback) {
callback(null, {'x': 'y'})
}
First off, not sure you want to do this in your componentWillMount, because your component will not render until all this is done, it's better to have it in componentDidMount and have some default states that will update once done with these requests. Second, you want to limit the number of setStates you write because they might cause additional re-renders, here is a solution using async/await:
async componentDidMount() {
const firstRequest = await axios.get(URL1);
const secondRequest = await axios.get(URL2);
const thirdRequest = await axios.get(URL3);
this.setState({
p1Location: firstRequest.data,
p2Location: SecondRequest.data,
p3Location: thirdRequest.data,
});
}
i'm working this way. you can use this
const token_config = {
headers: {
'Authorization': `Bearer ${process.env.JWD_TOKEN}`
}
}
const [ res1, res2 ] = await Axios.all([
Axios.get(`https://api-1`, token_config),
Axios.get(`https://api-2`, token_config)
]);
res.json({
info: {
"res_1": res1,
"res_2": res2
}
});
I want to set timeout in my fetch method, and I follow this github issue.
from #mislav answer, we could custom timeout method like below.
// Rough implementation. Untested.
function timeout(ms, promise) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error("timeout"))
}, ms)
promise.then(resolve, reject)
})
}
timeout(1000, fetch('/hello')).then(function(response) {
// process response
}).catch(function(error) {
// might be a timeout error
})
and improved by #nodkz
function timeoutPromise(ms, promise) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(new Error("promise timeout"))
}, ms);
promise.then(
(res) => {
clearTimeout(timeoutId);
resolve(res);
},
(err) => {
clearTimeout(timeoutId);
reject(err);
}
);
})
}
but I want to call that method in ES7 async/await syntax, I try below way but failed.
async request() {
try {
let res = await timeout(1000, fetch('/hello'));
} catch(error) {
// might be a timeout error
}
}
and how could I use it in ES7 async/await syntax?
thanks for your time.
update
thanks for #Bergi reply, and I display my code in http request step.
ES7 fetch
'use strict';
import { configApi, } from 'tyrantdb-config';
import { timeoutPromise, } from 'xd-utils-kit';
const keyResponse = configApi.keyResponse;
const KEY_DATA = keyResponse.data;
module.exports = {
async fetchLogin(url, params, dataRely) {
let {
self, processor, route,
storage, isLocalStoraged,
email, password, _warning, } = dataRely;
self.setState({ isWait: true, });
try {
let res = await timeoutPromise(10, fetch(url, params));
if (res.status >= 200 && res.status < 300) {
let resJson = await res.json();
let resData = resJson[KEY_DATA];
let cache = {
...resData,
password,
};
if (isLocalStoraged !== true) {
processor(cache, storage);
}
global.g_user = cache;
self.setState({ isWait: false, });
// clean user info which already bind to self[this]
self.email = self.password = null;
self.isLocalStoraged = false;
route();
} else {
console.log(`[login] response code: ${res.status}`);
self.setState({ isWait: false, });
_warning();
}
} catch(error) {
console.error(error);
}
},
saveLoginState: (cache, storage) => {
storage.save({
key: 'loginState',
rawData: cache,
});
},
openURL: (url, Linking) => {
Linking.canOpenURL(url).then(supported => {
if (!supported) {
console.log(`can\'t handle url: ${url}`);
} else {
return Linking.openURL(url);
}
}).catch((err) => {
console.log(`error occurred: ${err}`);
})
},
};
ES6 fetch
'use strict';
import { configApi, } from 'tyrantdb-config';
import { timeoutPromise, } from 'xd-utils-kit';
const keyResponse = configApi.keyResponse;
const KEY_DATA = keyResponse.data;
module.exports = {
fetchLogin(url, params, dataRely) {
let {
self, processor, route,
storage, isLocalStoraged,
email, password, _warning, } = dataRely;
self.setState({ isWait: true, });
timeoutPromise(1000, fetch(url, params))
.then((res) => {
if (res.status >= 200 && res.status < 300) {
return res.json();
} else {
console.log(`[login] response code: ${res.status}`);
self.setState({ isWait: false, });
_warning();
}
})
.then((resJson) => {
let resData = resJson[KEY_DATA];
let cache = {
...resData,
password,
};
if (isLocalStoraged !== true) {
processor(cache, storage);
}
global.g_user = cache;
self.setState({ isWait: false, });
// clean user info which already bind to self[this]
self.email = self.password = null;
self.isLocalStoraged = false;
route();
})
.catch(error => console.error(error))
.done();
},
saveLoginState: (cache, storage) => {
storage.save({
key: 'loginState',
rawData: cache,
});
},
openURL: (url, Linking) => {
Linking.canOpenURL(url).then(supported => {
if (!supported) {
console.log(`can\'t handle url: ${url}`);
} else {
return Linking.openURL(url);
}
}).catch((err) => {
console.log(`error occurred: ${err}`);
})
},
};
above ES6 fetch will catch output below, I think #Bergi is right, It's my code fault, not timeoutPromise error.
2016-06-08 22:50:59.789 [info][tid:com.facebook.React.JavaScript] [login] response code: 400
2016-06-08 22:50:59.808 [error][tid:com.facebook.React.JavaScript] { [TypeError: undefined is not an object (evaluating 'KEY_DATA')]
line: 103795,
column: 29,
sourceURL: 'http://172.26.129.189:8081/index.ios.bundle?platform=ios&dev=true' }
2016-06-08 22:50:59.810 [error][tid:com.facebook.React.JavaScript] One of the sources for assign has an enumerable key on the prototype chain. This is an edge case that we do not support. This error is a performance optimization and not spec compliant.
2016-06-08 22:50:59.810 [info][tid:com.facebook.React.JavaScript] 'Failed to print error: ', 'One of the sources for assign has an enumerable key on the prototype chain. This is an edge case that we do not support. This error is a performance optimization and not spec compliant.'