Get request with Basic authorization for React js app - reactjs

I try to do a get request with basic authentication using React JS. I try to do it as follows:
import React,{Component} from 'react';
import { encode } from "base-64";
export class MyDates extends Component{
constructor(props){
super(props);
this.state = {
items:[],
isLoaded:false,
}
}
componentDidMount(){
let url = 'https://gd.xxxxxx.com.tr/api/Dates';
let username = 'xxxxxxx';
let password = 'Bxxxxxxxxx';
fetch(url, {method:'GET', mode: 'no-cors', headers: {'Content-Type': 'application/json','Authorization': 'Basic ' + encode('${username}:${password}')}})
.then(res=>res.json())
.then(json => {
this.setState({
isLoaded:true,
items:json,
})
})
}
render(){
var {isLoaded,items} = this.state;
if(!isLoaded){
return<div>Loading...</div>;
}
else
{
return(
<div className='container'>
<h3>Randevularım sayfası</h3>
<div className='row'>
{items.map(item => (
//item.completed == true ?
<div className='col-md-4 px-4 py-2' key={item.MAHALLEID}>
<div className='m-2 rounded' style={{background:'#e2e2e2'}} >{item.MAHALLE}</div>
</div>
//:null
))};
</div>
</div>
)
}
}
}
Api, user and password checked.
I get the following error:
Failed to load resource: the server responded with a status of 401 ()
MyDates.js:19 Uncaught (in promise) SyntaxError: Unexpected end of input (at MyDates.js:19:1)
at MyDates.js:19:1
enter image description here

could you please try this. I hope this works.
componentDidMount(){
let url = 'https://gd.xxxxxx.com.tr/api/Dates';
let username = 'xxxxxxx';
let password = 'Bxxxxxxxxx';
const base64encodedData = Buffer.from(`${username}:${password}`).toString('base64');
fetch(url, {method:'GET', mode: 'no-cors', headers: {'Content-Type': 'application/json','Authorization': `Basic ${base64encodedData}`}})
.then(res=>res.json())
.then(json => {
this.setState({
isLoaded:true,
items:json,
})
})
}

Related

Can't Render Data with API Call

I've been stuck on this for quite some time now, I can't use a get request and have to use post as that is the only way I am able to get field values back. And no matter what I do, I can't get ANY data to render, as of right now, all i see is the loading... telling me that the data is null. yet I don't know how to change this. Any help would be appreciated.
this is using Fetch to call the QuickBase RESTful API to get multiple field values to just use as data points on line charts. I know this shouldn't be this hard, yet nothing I do can render any data. Using React as well.
import React, { Component } from 'react'
let headers = {
'QB-Realm-Hostname': 'XXXXXXXXXXX.quickbase.com',
'User-Agent': 'FileService_Integration_V2.1',
'Authorization': 'QB-USER-TOKEN XXXXXX_XXXXX_XXXXXXXXXXXXXXXX',
'Content-Type': 'application/json'
};
class JobsTableApi extends Component {
state = {
data: null,
}
componentDidMount() {
this.fetchData();
}
fetchData = () => {
let body = {"from":"bpz99ram7","select":[3,6,80,81,82,83,86,84,88,89,90,91,92,93,94,95,96,97,98,99,101,103,104,105,106,107,109,111,113,115,120,123,224,225,226,227,228,229,230,231,477,479,480,481],"sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":40,"grouping":"equal-values"}],"options":{"skip":0,"top":0,"compareWithAppLocalTime":false}}
fetch('https://api.quickbase.com/v1/records/query', {
method: 'POST',
headers: headers,
body: JSON.stringify(body)
}).then(res => res.json())
.then( res => {
this.setState({
data: [],
})
});
}
render() {
const { data } = this.state;
if (data === null) return 'Loading...';
return (
<div>
<h3>
{data}
</h3>
</div>
)
}
}
export default JobsTableApi;
some users have said to map through, but the problem is I don't know how with my current code. some say to use data.value yet it's an array. i've tried data[3], since there is no 'job name' field, or 'amount' field, it's all split up by number as shown above in my select body.
Thanks,
I guess the root cause is coming from using same names in the React's fetch and as a key in the QB response.
You can try to reach data by map via data["data"][item][6].value (6 is a field ID)
I have created and tested the following and it works properly.
<div id="mydiv"></div>
<script type="text/babel">
let headers = {
'QB-Realm-Hostname': 'XXXXXXXXXX.quickbase.com',
'User-Agent': 'FileService_Integration_V2.1',
'Authorization': 'QB-USER-TOKEN XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'Content-Type': 'application/json'
};
class JobsTableApi extends React.Component {
constructor(props) {
super(props);
this.state = {
data: null,
};
}
componentDidMount() {
this.fetchData();
}
fetchData = () => {
let body = {"from":"XXXXXXXXXXX","select":[3,6,7],"sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":6,"grouping":"equal-values"}],"options":{"skip":0,"top":0,"compareWithAppLocalTime":false}}
fetch('https://api.quickbase.com/v1/records/query', {
method: 'POST',
headers: headers,
body: JSON.stringify(body)
}).then(response => response .json())
.then(data => this.setState({ data }));
}
render() {
const { data } = this.state;
if (data === null) return 'Loading...';
return (
<ul>
{Object.keys(data["data"]).map(item =>
<li key={item}>
<a> {data["data"][item][6].value} </a>
</li>
)}
</ul>
)
}
}
ReactDOM.render(<JobsTableApi />, document.getElementById('mydiv'))
</script>

Keep on getting 400 (Bad Request) on a POST request

So I'm trying to make a request to a database I have set up. The point is to send a POST to add to the table and for it to feed my back the full list.
I keep on getting "POST http://localhost:8000/api/folders 400 (Bad Request)" in the console. I know it's the POST as when I check the database on both DBeaver and POSTman the database remains the same.
I tried writing '"name"' as 'name' and that didn't change anything.
const postfolder = {
method: 'POST',
body: JSON.stringify({ "name" : f })
};
const getFolder = {
method: 'GET'
};
fetch(`${config.API_ENDPOINT}/folders`, postfolder)
.then(
fetch(`${config.API_ENDPOINT}/folders`, getFolder)
)
.then(res => {
if (!res.ok)
return res.json().then(e => Promise.reject(e))
})
.then(folders => {
this.setState({folders : folders});
})
.catch( error =>{
console.error({ error });
console.log("I fucked up the coding: 001");
});
EDIT:
For clarity here is the component that defines f. Though I did have a console.log (not seen in above) that checks the value and it's giving me the correct one.
import React, {Component} from 'react';
//import { NavLink, Link } from 'react-router-dom'
import './AddFolder.css';
export default class AddFolder extends Component{
handleSubmit = (e) => {
e.preventDefault();
console.log("handleSubmit ran");
var nameError = document.getElementById("folderNameError");
if (!e.target.name.value){
nameError.classList.remove("hidden");
return console.log("no name");
}
nameError.classList.add("hidden");
return this.props.addNewFolder(e.target.name.value);
// process form values here
}
render(){
return (
<form className="folderForm" onSubmit={(e) => this.handleSubmit(e)}>
<h3>New Folder</h3>
<label>Text </label>
<input type="text" className="elementName" name="name" id="folderName"/>
<div>
<button type="submit" className="registration__button">
Save
</button>
</div>
<div>
<button type="reset" className="registration__button">
Cancel
</button>
</div>
<div className="errorSpace">
<p className="hidden" id="folderNameError">A name is required</p>
</div>
</form>
)
}
}
Here's a quick picture of the database. It's just a name and an id.
I'm able to fetch to it using POSTMAN so I don't believe it's the issue.
So I found out that the issue was that I needed to add to my fetch request.
I had it as:
const postfolder = {
method: 'POST',
body: JSON.stringify({ "name" : f })
};
It should be:
const postfolder = {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(newFolder)
};
I needed the content-type.

Reactjs how to call magento 2 api with bearer (the server responded with a status of 401 (unauthorized))

I'm try to use reactjs (from localhost:80) to call (http://m2.example.com:80) magento 2 api, but it only return Error: the server responded with a status of 401 (unauthorized)"
import React from "react";
import ReactDOM from "react-dom";
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: []
};
}
componentDidMount() {
fetch("http://m2.example.com/rest/V1/products?searchCriteria[page_size]=20",{
method: 'GET',
mode: 'no-cors',
credentials: 'include',
withCredentials: true,
headers: {
'Authorization': 'Bearer 3nsi1y7pcun1atvhs87dxmokymquofii',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{items.map(item => (
<li key={item.name}>
{item.name} {item.price}
</li>
))}
</ul>
);
}
}
}
/*const App = () => (
<div>
<h1>Hello world!!</h1>
</div>
)*/
ReactDOM.render(<MyComponent/>, document.getElementById("root"));
//ReactDOM.render(<App/>, document.getElementById("root1"));
Anyone know what's wrong with above code?
Try removing the mode: 'no-cors' and 'withCredentials: true' and handle CORS from the backend php magento2 - Please check this link on how to do it
fetch("http://m2.example.com/rest/V1/products?searchCriteria[page_size]=20",{
method: 'GET',
credentials: 'include',
headers: {
'Authorization': 'Bearer 3nsi1y7pcun1atvhs87dxmokymquofii',
'Content-Type': 'application/json'
}
After that it should work.

Method returning undefined even though fetch succeeds?

I have two components, Client and App, and a fetch function. App is the child component of Client. I want to update Client's state using the return value from the method App calls. However, Client's state response is undefined after the fetch. I'm not sure why this code does not work.
import React, { Component } from 'react';
import './App.css';
function post(user, token, data){
console.log('fetching...')
fetch(`/project`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic '+ btoa(user+':'+token),
},
body: JSON.stringify(data)
}).then(r => {
if (!r.ok)
throw Error(r.status);
r.json().then(r => {return(r)});
}).catch(error => {throw Error(error)})
}
class Client extends Component {
constructor(props) {
super(props);
this.state = {
user: '',
token: '111',
project: {'project':'demo'},
response: {},
};
this.updateState = this.updateState.bind(this);
};
updateState(){
const { user, token, project } = this.state;
post(user, token, project).then(text => this.setState({ response: text
}));
}
render() {
return (
<App updateState={this.updateState}/>
)
}
}
class App extends Component {
render() {
return (
<div className="App">
<button onClick={ () => {
this.props.updateState()} }>Fetch Project</button>
</div>
);
}
}
EDIT: I changed my post() to this and it works :)
async function post(user, token, data){
console.log('fetching...')
const response = await fetch(`/project`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic '+ btoa(user+':'+token),
},
body: JSON.stringify(data)
}).catch(error => {throw Error(error)});
if(!response.ok)
throw Error(response.status);
const obj = await response.json();
return(obj);
}
If you are working with promises, you can do something like this.
import React, { Component } from "react";
async function post() {
// fetch //
return await fetch("https://hipsum.co/api/?type=hipster-centric");
}
class Client extends Component {
constructor(props) {
super(props);
this.state = {
response: "12"
};
this.updateState = this.updateState.bind(this);
}
async updateState(res) {
const text = await res().then(res => res.text());
this.setState({ response: text });
}
render() {
return (
<>
{this.state.response}
<App updateState={this.updateState} />
</>
);
}
}
class App extends Component {
render() {
return (
<div>
<button
onClick={() => {
this.props.updateState(post);
}}
>
Fetch
</button>
</div>
);
}
}
export default Client;
sandbox
It will be nice to know all the code for the fetch function but I think the problem is mostly here:
this.props.updateState(post())
That call is synchronous and the fetching process isn't. You need a better approach with await or promises or a callback.

how to fetch and display API content Onsubmit

I am developing a weather forecast app using Reactjs but i'm having a hard time Fetching/displaying API data
I know this question might have a duplicate but i have looked up all related problems/solutions on this platform and elsewhere but none solved my problem
//const API;
class WeatherApp extends React.Component{
constructor(props){
super(props);
this.state = {
location: "",
reports:[]
}
}
//functions should be written outside the constructor method
onSubmit = event => {
//prevents default loading of the page when this function "onSubmit"
//is called
event.preventDefault();
//saving the value of the textbox to a variable/const
if(this.searchbox.value !== ""){
const searchResult = this.searchbox.value;
//update the state object
this.setState({
location: searchResult + " weather report"
});
}else{
alert("please ensure that field is not empty!");
return;
}
};
componentDidMount(){
if(this.searchbox.value !== ""){
fetch(`api.openweathermap.org/data/2.5/forecast?q=london,uk ${/*this.searchbox.value +*/ KEY}`,{
method: "GET",
dataType: "JSON",
headers: {
"Content-Type": "application/json; charset=utf-8",
}
})
.then(response => { response.json() })
.then(data => {
console.log(data);
this.setState({ reports: data.list})
});
}
}
render(){
return(
<div className="weather-app">
<WeatherAppHeader />
<div className="weather-body">
<div className="entry-pane">
<form onSubmit ={this.onSubmit} >
<input
type="text"
id="search-box"
placeholder="Location e.g Abuja, NG"
size="40"
ref={input => this.searchbox = input} />
<button type="submit" id="search-btn">search</button>
</form>
</div>
<SearchedLocation location={this.state.location} />
<WeatherReport reports={this.state.reports} />
</div>
</div>
);
}
}
const WeatherAppHeader = () => (
<nav> WEATHER FORECAST </nav>
);
const SearchedLocation = ({location}) => (
<div className="searched-loc">{location}</div>
);
SearchedLocation.propTypes = {
location: PropTypes.string
}
///Declaring state within the WeatherReport component
const WeatherReport = ({reports}) => (
<div className="weather-report" >
<ul className="report-list">
{reports.map(report => (
<li key={report.id} className="daily-report">
<span className="daily-report-day">{report.day}</span><br/>
<span className="daily-report-icon">{report.icon}</span><br/>
<span className="daily-report-temp">{report.main.temp}</span>
</li>
))}
</ul>
</div>
);
WeatherReport.propTypes = {
report: PropTypes.array
}
ReactDOM.render(<WeatherApp />, document.getElementById('root'));
i want to display all data from the API on the browser console when the form is submitted but to no avail...and theres no error message. pls can anyone help?
After your fetch call, you are not correctly returning the response when you do .then(response => { response.json() }). Just remove the curly-braces, that way you do an implicit return. Otherwise, if you use curly-braces you must explicitly write .then(response => { return response.json() })
Working code:
componentDidMount(){
if(this.searchbox.value !== ""){
fetch(`api.openweathermap.org/data/2.5/forecast?q=london,uk ${/*this.searchbox.value +*/ KEY}`,{
method: "GET",
dataType: "JSON",
headers: {
"Content-Type": "application/json; charset=utf-8",
}
})
.then(response => response.json())
.then(data => {
console.log(data);
this.setState({ reports: data.list})
});
}
}

Resources