Getting Json fetched data on second attempt - javascript

I am getting my fetched Json data on second attempt. I have to refresh my screen two times to get the data. Thoughts?
var data = [];
class Profiel extends Component {
constructor(props) {
}
componentDidMount() {
this.setState({fetching:true},()=>{
this.getData().then(JsonData => data=JsonData).then(console.log(data));
});
}
getData(){
return fetch('https://Domain.eu.auth0.com/userinfo', {
method: 'GET',
headers: {
Authorization: 'Bearer ' + token,
},
}).then((response) => {return response.json()})
};

Related

React Native wait for one API call to finish before executing any others

I'm writing an app in react native that needs to make a call to an API to receive a bearer token that it will use for all other API calls but I'm having difficulty making sure that the call to get the token finishes before any other calls are made.
I have a basic APIHelper class which is going to contain wrapper functions for all the API calls the app needs to make, here's a reduced version of it:
export class APIHelper {
constructor(baseURL) {
this.baseURL = baseURL;
this.token = null;
}
setToken(token) {
this.token = token;
}
getToken(username, password) {
var url = this.baseURL + `/token/${username}/${password}`;
fetch(url, {
method: "GET",
header: {
"Content-Type": "application/json"
}).then(response => response.json())
.then((data) => {
this.setToken(data["access_token"]);
});
}
getRequest(endpoint) {
fetch(this.baseUrl + endpoint, {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + this.token
}
}).then(response => response.json())
.then((data) => {
console.log(data);
});
}
}
Here is a reduced version of my App.js:
var apiHelper = new APIHelper("URLGoesHere");
class StarterApp extends React.Component {
render() {
apiHelper.getToken("UsernameGoesHere", "PasswordGoesHere");
var users = apiHelper.getRequest("/users");
console.log(users);
return (
//App Content Here
);
}
}
I've tried a number of different things: Making the API calls asynchronous, instituting a check in the getRequest function to wait until token isn't null but that just seems to hang, moving the calls into the constructor for the App. Is what I'm looking to do possible? Or will I need to make a call to get the token every time I want to make an API call?
Also: I understand that this is not a particularly secure API, it's a temporary system for a school project, please do not provide feedback on that.
If you return the fetch calls which are promises from getRequest, getToken you can ensure that the call to getToken completes before getRequest using await. Also run the code in componentDidMount as suggested by Chris G e.g.
export class APIHelper {
constructor(baseURL) {
this.baseURL = baseURL;
this.token = null;
}
setToken(token) {
this.token = token;
}
getToken(username, password) {
var url = this.baseURL + `/token/${username}/${password}`;
return fetch(url, {
method: "GET",
header: {
"Content-Type": "application/json"
}).then(response => response.json())
.then((data) => {
this.setToken(data["access_token"]);
});
}
getRequest(endpoint) {
return fetch(this.baseUrl + endpoint, {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + this.token
}
}).then(response => response.json())
.then((data) => {
console.log(data);
});
}
}
var apiHelper = new APIHelper("URLGoesHere");
class StarterApp extends React.Component {
async componentDidMount() {
try {
await apiHelper.getToken("UsernameGoesHere", "PasswordGoesHere");
await var users = apiHelper.getRequest("/users");
console.log(users);
} catch (e) {
console.log(e)
}
}
render() {
return (
//App Content Here
);
}
}

Response from API returns data, state is undefined - React.JS

I have a REACT component:
import React from 'react';
import Weather from '../service/weatherAPI.js';
export default class DisplayWeather extends React.Component {
constructor(props){
super(props);
this.state = {
weatherData: []
}
this.getWeatherData = this.getWeatherData.bind(this);
}
componentDidMount(){
this.getWeatherData();
}
async getWeatherData(){
let data = await Weather(this.props.location)
this.setState({ weatherData: data});
console.log(this.state.weatherData)
}
This function references a function exported from another file which is using fetch to call an endpoint. All the data returns correctly from the endpoint I am calling. However, when trying to set this data onto the state, my data is undefined.
Below is my API call, just in case I have missed anything here:
const Weather = (location) => {
fetch(url, {
Method: 'GET',
headers : {
'Accept': 'application/json'
},
})
.then((raw) => raw.json())
.then((response) => {
return response
})
}
export default Weather;
Thanks in advance.
You need to return the promise like this in your weather function:
const Weather = (location) => {
return fetch(url, {
Method: 'GET',
headers : {
'Accept': 'application/json'
},
})
.then((raw) => raw.json())
.then((response) => {
return response
})
}
That way the await is working on the promise instead of just the function.

Post action API with object parameter within the URL

I've got an API where some of the parameters need to be given within the URL.
Example of how my api url looks like: https://www.server.com/api/actions/execute?auth_type=apikey&data={"Name": "name","Email" : "email"}
What my code looks like right now
register = async () => {
let data = {"Name":this.state.name, "Email":this.state.email}
data = JSON.stringify(data)
let URL = 'https://www.server.com/api/actions/execute?auth_type=apikey&data=';
fetch(URL, {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: data
})
.then((response) => response.text())
.then((responseText) => {
alert(responseText);
})
.catch((error) => {
console.error(error);
});
}
The response I get on my device:
{"code":"succes","details":{"userMessage":["java.lang.Object#2e56000c"],"output_type":void","id:"20620000000018001"},"message":"function executed succesfully"}
This is alle working fine when I test it in postman but I can't get it to work within React-Native. I've tried stuff like 'Content-Type':'application/x-www-form-urlencoded' already.
First install the package axios from the url https://www.npmjs.com/package/react-native-axios
Then create two service for handling get and post request so that you can reuse them
GetService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const GetService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.get(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
PostService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const PostService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.post(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
Sample code for using get and post services is given below
import { PostService } from './PostService';
import { GetService } from './GetService';
let uploadData = new FormData();
uploadData.append('key1', this.state.value1);
uploadData.append('key2', this.state.value2);
//uploadData.append('uploads', { type: data.mime, uri: data.path, name: "samples" });
let jwtKey = ''; // Authentication key can be added here
PostService(uploadData, 'postUser.php', jwtKey).then((resp) => {
this.setState({ uploading: false });
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
GetService({}, 'getUser.php?uid='+uid, jwtKey).then((resp) => {
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
If you need to pass parameters via URL you should use GET, if you use POST then the parameters should be passed in the body

Axios and response data set split to multiple arrays

I'm trying to get data from an API using axios command like
function fetchData(apiURL){
let data = [];
let options = {
method: "GET",
url: apiURL,
headers: {
"Access-Control-Allow-Origin": "*"
},
credentials: "include"
};
axios(options)
.then(response => {
data = response.data;
console.log(data);
})
.catch(function (error) {
console.log("System error : " + error);
});
return data;
}
but that will produce sets of arrays which will store arrays of JSONs from response.data in count of 100 per array set.
I haven't had problem using fetch() to retrieve all data. How I can get similar response of one large array of JSON objects instead of a split?
PS.
I have triggered that function in the
componentDidMount() {
const apiURL = process.env.REACT_APP_API;
let tableData = fetchData(apiURL);
console.log("DATA " + JSON.stringify(tableData));
this.setState({tblData : tableData});
}
Axios requests are asynchronous and return promises, so you need to adjust your example a bit so that your function returns a promise.
/**
* #return {Promise<T>}
*/
function fetchData(apiURL){
const options = {
method: "GET",
url: apiURL,
headers: {
"Access-Control-Allow-Origin": "*"
},
credentials: "include"
};
return axios(options)
.then(response => {
return response.data;
})
}
Now, when you consume this API do so asynchronously.
function somethingThatUpdatesThatUI() {
fetchData("/api/foo/bar")
.then((data) => {
//perform updates to UI or state here
})
.catch((err) => {
//alert the users that an error has happened here
})
}
You can update the componentDidMount function:
componentDidMount() {
const apiURL = process.env.REACT_APP_API;
fetchData(apiURL).then(data => {
console.log(data ${JSON.stringify(tableData)})
this.setState({tblData : data});
})
}

Can not make Post request in react

I'm trying to make a POST in react, and I have an error that says {"error_description":"Missing grant type"}
in postman works fine, what am I doing wrong?
Thanks!
Here is my code
class App extends Component {
constructor() {
super()
this.state = {
info : null
}
}
componentDidMount() {
var payload = {
client_id: 'my_site',
grant_type: 'my_credentials',
client_secret: 'xxx',
}
var data = new FormData();
data.append("json",JSON.stringify(payload));
fetch('/myendpoint', {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: data
})
})
.then(function(res){
return res.json();
})
.then(function(data){
alert( JSON.stringify( data ) )
})
When you make the post request define the type when: URL Encoded but you send a JSON
Try to make the request with the next format:
fetch('/myendpoint?client_id="some id"&grant_type="some type"', {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
})
Because your values its on the URL
Make the post without body

Categories

Resources