React & NodeJS shows the URI is malformed error - reactjs

I recently moved my workspace to Linux centOS from Windows10. When I run this code in Windows 10. It works and I am able to upload file to the server. But when I change the environment to CentOS. It still show the output but it does not send file to the server and show error "URI is malformed"
here are my codes
import React from 'react';
import axios from 'axios';
import Swal from 'sweetalert2';
import withReactContent from 'sweetalert2-react-content';
const MySwal = withReactContent(Swal);
const BASE_URL = 'http://localhost:5000';
class UploadPDF extends React.Component {
constructor(props)
{
super(props);
this.state =
{
images: [],
imageUrls: [],
message: ''
}
}
selectImages = (event) =>
{
let images = []
for (var i = 0; i < event.target.files.length; i++)
{
images[i] = event.target.files.item(i);
}
images = images.filter(image => image.name.match(/\.(pdf)$/))
let message = `${images.length} valid File(s) selected`
this.setState({ images, message })
}
uploadImages = () =>
{
MySwal.fire('File Uploaded','The File Is Uploaded!','success'
);
const uploaders = this.state.images.map(image =>
{
const data = new FormData();
data.append("image", image, image.name);
// Make an AJAX upload request using Axios
return axios.post(BASE_URL + 'upload', data)
.then(response =>
{
this.setState(
{
imageUrls: [ response.data.imageUrl, ...this.state.imageUrls ]
});
})
});
axios.all(uploaders).then(() =>
{
console.log('done');
}).catch(err => alert(err.message));
}
render() {
console.log("Header - Rendered");
return(
<div className="container">
<div className="py-5 text-center">
<div className="jumbotron">
<div className="container">
<h1>Upload File</h1>
<hr/>
<p className="lead">Only PDF</p>
<input className="form-control " type="file" onChange={this.selectImages} multiple />
<p className="text-info">{this.state.message}</p>
<button className="btn btn-primary" value="Submit" onClick={this.uploadImages}>Submit</button>
</div>
</div>
</div>
</div>
);
}
}
export default UploadPDF;
This is the code I am stuck and dunno what to do. any links or suggestion ?

It's hard to tell exactly what's going on but my guess is you're combining the string in BASE_URL with "upload" so you wind up trying to post to http://localhost:5000upload rather than http://localhost:5000/upload.
Try adding a trailing slash on BASE_URL and see if that fixes your problem.
This said, I'm not sure why the OS would make a difference.

Related

Show pull request list with Github API from a specific repository

I'm remaking my previous question. I'm working on a project that shows a repository list from github api.
It's working fine, I get all the repo info from the api but I need that when I click in one button from a particular repository, it shows the pull request info from https://api.github.com/repos/:USER:/:REPONAME:/pulls in the modal i have made.
But i have no idea how to do it. Can someone help me?
import React, { Component } from "react";
import axios from "axios";
import Navbar from "./components/Navbar";
import Modal from "react-modal";
class App extends Component {
constructor() {
super();
this.state = {
githubData: [],
isActive: false
};
}
componentDidMount() {
axios
.get(
"https://api.github.com/search/repositories?q=language:Java&sort=stars&page=1"
)
.then((res) => {
console.log("res", res);
this.setState({ githubData: res.data.items });
});
Modal.setAppElement("body");
}
toggleModal = () => {
this.setState({
isActive: !this.state.isActive
});
};
render() {
const { githubData } = this.state;
return (
<div className="container">
<Navbar />
<div className="row">
{githubData.map((name, index) => (
<div className="col-md-12" key={name.id}>
<img src={name.owner.avatar_url} alt="Imagem do projeto" />
<h1>
Projeto:
{name.name}
</h1>
<h1>
Autor:
{name.owner.login}
</h1>
<h1>
Descrição:
{name.description}
</h1>
<h1>
Link:
<a href={name.homepage}>{name.homepage}</a>
</h1>
<h1>
Stars:
{name.stargazers_count}
</h1>
<button onClick={this.toggleModal}>
Open pull request for this repository
</button>
<Modal
isOpen={this.state.isActive}
onRequestClose={this.toggleModal}
>
<p onClick={this.toggleModal}>
PULL REQUEST LIST FROM THIS REPOSITORY
</p>
</Modal>
</div>
))}
</div>
</div>
);
}
}
export default App;
The modal is working, i just need to get the pull request info from the api but no idea how to get from a specific repository.
After sometime i made it work.
I just created a new component, using axios to call the github api and passing as props the user and repo.
Heres the code:
import React from "react";
import axios from "axios";
const PullRequest = (props) => {
axios
.get(
"https://api.github.com/repos/" + props.user + "/" + props.repo + "/pulls"
)
.then((repo) => {
console.log("repo", repo);
});
return (
<div>
<p>Nome do repositório: {props.repo}</p>
<p>Nome do usuário: {props.user}</p>
</div>
);
};
export default PullRequest;
Cheers :)
Checkout my GitHub Open Source project, which I do just that and more using a Node.js REST server:
https://github.com/ConfusedDeer/Git-Captain
Here is an example of how one would do with Node.js (see GitHub Project for full example):
else if ((appName === 'gitCaptain') && (webServ === 'searchForPR')) //create Branches
{
var urlForPRsearch = gitHubAPIendpoint + "/repos/" + orgName + "/" + req.body.repo + "/pulls?" + "state=" + req.body.state + "&base=" + req.body.prBaseBranch + "&" + req.body.token;
// noinspection JSDuplicatedDeclaration
var options = {
method: 'GET',
url: urlForPRsearch,
headers: {
'User-Agent': 'request'
}
};
function callbackForPRSearch(error, response) {
if (!error && response.statusCode === 200) {
res.send(response);
}
else {
res.send(response); //send back response if not 200, but needs to be updated to handle exception.
}
}
request(options, callbackForPRSearch);
}

React + axios async call

I am using axios to fetch some data on the componentDidMount lifecycle method. The call was originally in the same file and thus i could update this.setState({members}). however I wanted to abstract the logic into a serperate file to keep the code clean.
I split the logic into a new file and start using the axios async await pattern. hoewever it seems like React doesn't wait for my axios call to finish. I went throught the docs and several posts but I cannot seem to find the problem. any hints are appreciated!
PS: I used create react app as base and added the dns mock:
https://github.com/hapijs/isemail/issues/26
Teamcard file
import React from "react";
import { Icon } from "office-ui-fabric-react/lib/Icon";
import { PrimaryButton } from "office-ui-fabric-react/lib/Button";
import TeamCardLogo from "./teamCardLogo/teamCardLogo";
import TeamCardPersona from "./teamCardPersona/teamCardPersona";
import { GetGroupMembers } from "../../HttpRepositories/graphRepository";
class TeamCard extends React.Component {
state = {
members: ""
};
componentDidMount() {
let members = GetGroupMembers(this.props.id, 5);
console.log("members", members);
this.setState({ members });
}
render() {
let members = "";
if (
typeof this.state.members !== "undefined" &&
this.state.members.length > 0
) {
members = this.state.members.map((member, i) => {
return (
<div className="team-card-body__personas-wrapper-person" key={i}>
<TeamCardPersona
className="team-card-body__personas-wrapper-person"
member={member}
key={i}
/>
</div>
);
});
}
let favouriteIcon = "";
this.props.isFavorite === true
? (favouriteIcon = <Icon iconName="FavoriteStarFill" />)
: (favouriteIcon = <Icon iconName="FavoriteStar" />);
return (
<article className="team-card-wrapper">
<header className="team-card-wrapper__header">
<TeamCardLogo
className="team-card-wrapper__header-photo"
teamId={this.props.id}
/>
<div className="team-card-wrapper__header-options-wrapper">
<div className="header-options__icon-group">
<div className="header-options__group-type">
<Icon iconName="LockSolid" />
</div>
</div>
<div className="header-options__icon-group">
<div className="header-options__favourite">{favouriteIcon}</div>
</div>
</div>
</header>
<section className="team-card-body">
<h1>{this.props.title}</h1>
<h2>Leden: {this.props.memberCount}</h2>
<div className="team-card-body__personas-wrapper">{members}</div>
<p className="description">{this.props.description}</p>
<div className="team-card-body__join-button-wrapper">
<PrimaryButton text="Lid worden" />
</div>
</section>
</article>
);
}
}
export default TeamCard;
seperated get request file:
import { getGraphToken } from "../adalConfig";
import axios from "axios";
import { resolve } from "dns";
export async function GetGroupMembers(groupId, numberOfMembers) {
// we initiate a new token, to be sure that it didn't expire.
let graphToken = getGraphToken();
let response = await axios({
url: `https://graph.microsoft.com/v1.0/groups/${groupId}/members?$top=${numberOfMembers}`,
method: "GET",
headers: { Authorization: "Bearer " + graphToken }
});
if (response.status != 200 && response.status != 204) {
console.log("error");
}
console.log("returning data", response.data.value);
return response.data.value;
}
Screenshot of logging:
You are missing an await here: let members = await GetGroupMembers(this.props.id, 5); and componentDidMountmust be declared async.

how to iterate through json data from api in react.js

I just started learning React and am trying to loop through an array of JSON data. However, I am getting some syntax errors. I'm trying to use the array.map function, but it's not working properly, and I'm not exactly sure how to implement it to make it display each element in the JSON array instead of just one. Any help is greatly appreciated - thanks!
import React, { Component } from 'react';
import axios from "axios";
import './App.css';
import UserForm from "./components/UserForm.js";
class App extends Component {
state = {
name: "",
stars: "",
icon: "",
trails: [], isLoaded: false
}
getUser = (e) => {
e.preventDefault();
const address = e.target.elements.address.value;
if (address) {
axios.get(`https://www.hikingproject.com/data/get-trails?lat=40.0274&lon=-105.2519&maxDistance=10&key=200279581-dd891420fa2c470dbb683b34e017062a`)
.then((res) => {
console.log(res);
const trailList = res.data.trails.map((trail) => {
console.log(trail.name)
console.log(trail.stars)
return <div> <p>{trail.name}</p> </div>
})
this.setState({ trails: trailList, isLoaded: true });
const name = res.data.trails.name;
const stars = res.data.trails.stars;
const icon = res.data.trails.imgMedium;
this.setState({ name });
this.setState({ stars });
this.setState({ icon });
})
}
else return;
}
render() {
return (
<div>
<div className="App">
<header className="App-header">
<h1 className="App-title">HTTP Calls in React</h1>
</header>
<UserForm getUser={this.getUser} />
<div className="newmessage">
{this.state.trails.map((obj) => {
return(
<div>
<p>{obj.name}</p> >
<p> {obj.stars}</p>
</div>
);
}}
</div>
</div>
</div>
</div>
);
}
};
export default App;
A good start would be to fetch your data in the componentDidMount either with fetch or axios. Never used axios, so I am going to answer the question with fetch
Leave the constructor as it is. Then write a componentDidMount like so:
componentDidMount() {
fetch('https://www.hikingproject.com/data/get-trails?lat=40.0274&lon=-105.2519&maxDistance=10&key=200279581-dd891420fa2c470dbb683b34e017062a')
.then(res => res.json())
.then(data => this.setState({ trails: data.trails }))
.catch(e => console.log(e))
}
then in a sub-render method, such as renderData, write the following code:
renderData() {
if (!this.state.trails) {
return null;
}
return this.state.trails.map(trail => <p>{trail.name}</p>);
}
Then call {this.renderData()} in your render
render() {
return (
<div>{this.renderData()}</div>
)
}
This code has been tested on my local environment and it was working as it should.

State changes without setState on key

I'm (very) new to React and am building a small web page as part of my learning process. My web page is a table of currencies (given using an API) and I should be able to delete and add currencies and revert to the table's original state.
Deleting as many as I want and then reverting a first time works fine. When I delete and then revert a second time - nothing happens.
My App's state has a 'shownData' attribute, holding the data currently presented in the table, and an 'initialData' attribute, holding the original data I should present when clicking 'revert'.
From my debugging process, it seems that clicking the 'revert' button ties 'initialData' to 'shownData', so that when reverting a second time nothing happens.
Here's the code for my main App component:
import React, { Component } from 'react';
import CurrencyTable from './currencyTable';
import SearchBar from './searchBar';
// import _ from 'lodash';
import RevertButton from './revertButton';
import logo from './logo.svg';
import './App.css';
import './bootstrap.min.css';
const API_KEY = '7312269b011ac267b5d9663c4a479c24';
const endpoint = 'latest';
class App extends Component {
constructor(props){
super(props);
this.state={
shownCountries: [],
initialCountries: [],
allData: [],
shownData:[],
initialData:[],
value:'',
}
}
componentDidMount(){
this.setState({shownCountries: ['EUR', 'ILS', 'USD', 'GBP', 'AUD']});
this.setState({initialCountries: ['EUR', 'ILS', 'USD', 'GBP', 'AUD']});
// localStorage.setItem('shownC', JSON.stringify(this.shownCountries));
const cachedCountries = localStorage.getItem('shownC');
if (!cachedCountries)
localStorage.setItem('shownC', JSON.stringify(this.state.shownCountries));
else
this.setState({shownCountries: JSON.parse(cachedCountries)});
fetch(`http://data.fixer.io/api/${endpoint}?access_key=${API_KEY}`)
.then(results => {
return results.json();
})
.then(result => {
let rates = result.rates;
let shownData = [];
let initialData = [];
let allData = [];
let i = 0;
let j = 0;
let k = 0;
//check for saved data in local storage:
Object.keys(rates).forEach(key => {
if (this.state.shownCountries.indexOf(key) > -1){
shownData[j] = {rate: key, value: rates[key], button: "btn btn-danger red"};
j++;
}
if (this.state.initialCountries.indexOf(key) > -1){
initialData[k] = {rate: key, value: rates[key], button: "btn btn-danger red"};
k++;
}
allData[i] = {rate: key, value: rates[key], button: "btn btn-danger red"};
i++;
})
this.setState({allData: allData, initialData: initialData, shownData: shownData});
})
}
findValue(rate){
for (let i=0; i<this.state.allData.length; i++){
if (this.state.allData[i].rate === rate)
return this.state.allData[i].value;
}
}
handleChangeValue = value => {
let newRateObj = {rate: value, value: this.findValue(value), button: "btn btn-danger red"};
this.setState({
shownData: this.state.shownData.concat([newRateObj])
});
this.state.shownCountries.concat([value]);
localStorage.setItem('shownC', JSON.stringify(this.state.shownCountries));
}
handleRevertClick = () => {
console.log(this.state.initialData);
localStorage.setItem('shownC', JSON.stringify(this.state.initialCountries));
this.setState({shownData: this.state.initialData});
console.log(this.state.initialData);
};
saveToLocalStorage(data) {
localStorage.setItem('shownC', JSON.stringify(this.getShownCList(data)));
}
getShownCList(data){
let shownC = [];
for (let i=0;i<data.length;i++){
shownC.push(data[i].rate);
}
// console.log(shownC);
return shownC;
}
render() {
console.log("initialData is:");
console.log(this.state.initialData);
if (this.state.initialData.length===0)
return 'loading...';
return (
<div className="headDiv">
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Niki's React Currency App</h1>
</header>
</div>
<div className="mainDiv">
<div className="col">
<div className="col-lg-6 currencyTableContainer">
<CurrencyTable
data = { this.state.shownData }
saveToLS= {(data) => {
this.saveToLocalStorage(data)}}/>
</div>
<div className="col-lg-6 searchAndRevertContainer">
<div className="row">
<div className="row-md-4">
<SearchBar
value={this.state.value}
allData = { this.state.allData }
onChangeValue={this.handleChangeValue}/>
</div>
<div className="row-md-4 revertButton">
<RevertButton
onClick={this.handleRevertClick}/>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default App;
And here's the code for the onClick function in the table component, that deletes a row (after which initialData seems to go wrong):
onRemoveClick(rate){
const newShownData = this.state.myTableData;
let index = _.findIndex(newShownData, {rate: rate});
if (index>-1)
newShownData.splice(index, 1);
this.setState({myTableData: newShownData});
this.props.saveToLS(this.state.myTableData);
}
I'm super lost, help? :)
Solved by creating a deep copy of initialData before giving its value to shownData:
...
var temp = JSON.parse(JSON.stringify(this.initialData))
this.setState({shownData: temp});
...

React App: How to display data from api using fetch

I am trying to display school data from an external api using React. I'm just trying to display a school name to start. The school name appears in the console, but it doesn't show up in the browser.The api call is correct, as it works in Postman. Here is my code:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
schoolName: '',
// schoolData: {}
}
}
fetchSchool(event) {
event.preventDefault();
const apiKey = 'XdOHSc8fKhMKidPu2HWqCZmMy9OxtCJamGC580Bi';
const fields = `_fields=school.name,2015.aid.median_debt.completers.overall,2015.cost.tuition.in_state&school.name=${this.state.schoolName}`;
const requestUrl = `https://api.data.gov/ed/collegescorecard/v1/schools?&api_key=${apiKey}&${fields}`;
const school = fetch(requestUrl).then((res) => res.json()).then((data) => console.log(data.results[0]['school.name']));
this.setState({
schoolName: school
// schoolData: school
})
console.log(this.state.schoolName);
}
setSchool(event) {
event.preventDefault();
this.setState({
schoolName: event.target.value
});
}
render() {
// const schoolname = this.state.schoolName[0];
// const {schooName} = this.state;
return (
<div>
<form action="/school" method="GET" id="myform">
<input type="text" className="form-control" id="enter_text" onChange={this.setSchool.bind(this)} />
<button onClick={this.fetchSchool.bind(this)} type="submit" className="btn btn-primary" id="text-enter-button button submit">Submit</button>
</form>
<div>
<p>School: {this.state.school} </p>
</div>
</div>
);
}
}
export default App;
fetch is asynchronous. Therefore, setState is being called before the data has been fetched.
To fix this, call this.setState from inside of your then function
const school = fetch(requestUrl)
.then((res) => res.json())
.then((data) => {
console.log(data.results[0]['school.name'])
this.setState({
schoolName: data.results[0]['school.name'],
schoolData: data.results
})
});
In your render method change this line because schoolName is your state variable and not school.
<p>School: {this.state.school} </p>
to
<p>School: {this.state.schoolName} </p>

Resources