I create some spring + react.js application and one of the main function of that is show news from the MySQL database. But when I try to fetch JSON using react function that returns me nothing.
I added 'Content-Type': 'application/json', 'Accept': 'application/json' to the fetch React function, but that not help.
React component:
class News extends Component {
constructor(props) {
super(props);
this.state = {
news: []
}
};
ourFunction = () =>{
const response = fetch('/news/all',{
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
console.log(response);
const body = response.json;
console.log(body);
this.setState({news : body });
console.log(this.state.news);
};
render() {
return (
<div className="news">
<span onClick={this.ourFunction}>Click{}</span>
<div className="news_bar"> Новини</div>
{defaultNewsData.map(({title, content, date}) => <AccordionContainer
title={title}
content={content}
date={date}
/>)}
</div>
);
}
}
export default News;
Spring controller:
#RestController
#RequestMapping(path = "/news")
public class NewsController {
#Autowired
private NewsRepository newsRepository;
#GetMapping("/add")
public String addNewNews(#RequestParam String title, #RequestParam String content){
News news = new News();
news.setTitle(title);
news.setContent(content);
newsRepository.save(news);
return "News Saved";
}
#GetMapping(path = "/all")
public Iterable<News> getAllNews(){
return newsRepository.findAll();
}
}
Expected: to fetch JSON object to the javascript and parse it to the HTML.
Actual: I receive nothing, that is shown on the console.
Related
I am trying to create very simple react app that can create POST requests. The API that I am trying to reach is password protected so I tried having Authorization header in post request but couldn't get it working. Any help would be appreciated.
import React, {Component} from 'react';
import './App.css';
class App extends Component{
async postData(){
try {
let result = await fetch('https://u0l8meat1b-u0dl1g7crl-connect.us0-aws.organization.io/gateways/simplestoragedev/',{
method : 'POST',
mode: 'no-cors',
headers: {
'Authorization' : 'Basic dTB2eHRtNjZlcjpwUTcxalVtZFZ1Sm9BE0hHVXREaDFRajF5cjBCbGVEY25BWjBMNkdnREhJCg',
'Content-Type': 'application/json',
},
body: JSON.stringify({
x : "2"
})
})
console.log('Result:' + result)
}catch (e){
console.log(e);
}
}
render(){
return (
<div className = "App">
<button onClick = { () => this.postData()}>Press</button>
</div>
);
}
}
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>
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.
I am working on file upload React with web API. After uploading the file, server side shows that
null.,..................................................................
import React, { PropTypes } from 'react';
import axios from 'axios';
class Dashboard extends React.Component {
constructor(props){
var files;
super(props);
this.state = {
selectedFile: null
}
}
fileChangedHandler = event => {
this.setState({
selectedFile: event.target.files[0]
})
var file = this.refs.file.files[0].name;
let reader = new FileReader();
reader.onloadend = () => {
this.setState({
imagePreviewUrl: reader.result
});
}
reader.readAsDataURL(event.target.files[0])
}
async submit(e){
e.preventDefault();
await this.addImage(this.state.selectedFile);
};
addImage = async (file) => {
console.log(this.state.selectedFile);
await fetch('http://localhost:32188/Api/Authenticate/Uploadfile',
{
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: this.state.selectedFile
}
)
}
render() {
<form onSubmit={e => this.submit(e)} enctype="multipart/form-data">
<input ref="file" type="file" name="user[image]" onChange={this.fileChangedHandler} style={{padding: '5px', marginLeft: '31px'}} />
<div className="signin_form_button">
<input type="submit" value="Upload" className="signin_form_buttonstyle" />
</div>
</form>
}
}
Serverside Code
Model
public class ImageModel
{
public IFormFile File { get; set; }
}
Controller
[System.Web.Http.Route("Api/Authenticate/Uploadfile")]
[System.Web.Http.HttpPost]
public void CreateImage([System.Web.Http.FromBody] ImageModel model)
{
var file = model.File;
}
Following Error Message is displayed
500 Internal Server Error Occurred
Message: "An error has occurred."
ExceptionMessage: "Object reference not set to an instance of an object."
Please Help.
Link:https://codesandbox.io/s/vigorous-mestorf-osf90
I am having trouble saving the data from a fetch post request using Node.js and React.js. I am calling the fetch request from a function inside a React component class. I want to query some userid from my database then save it to one of the React component instance variables ie "this.userid" however, whenever I assign the value to one of the empty variables I check it outside of the ".then" statements you can see it was never assigned.
Does anyone know of a run around or the proper way to perform the fetch request? I am creating a simple login post request and want to save the userid once its returned from the API.
class LandingPage extends React.Component {
constructor(props) {
super(props)
this.data = data
}
login(e){
var that = this;
function log(id){
that.userid = id
}
fetch("/login", {
method: "POST",
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
},
body: JSON.stringify(this.data)
}).then(response => {
return response.json();
})
.then(json =>log(json.userid))
/both show undefined
console.log(that.userid, this.userid)
}
You are checking the data outside of the then scope. It doesn't exist there, so you will have to call setState with the retrieved data inside the .then().
change
.then(json =>log(json.userid))
to
.then(json => {
that.setState({userid: json.userid})
})
then, after the component updated, the state with userid is available
Update: alternatively, you can use async await and build it like this:
import React from 'react';
class MyComponent extends React.Component {
state = {
userId: null
}
useFetch = async e => {
const raw = await fetch("/login", {
method: "POST",
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type': 'application/json'
},
body: JSON.stringify(this.data)
});
const json = await raw.json();
this.setState({
userId:json
}, () => console.log(this.state))
}
render() {
if (this.state.userId === null)
this.useFetch();
return (
<div>Loading some data</div>
)
}
}
export default MyComponent;
tested and working component.