External API issue in production - React.js - javascript

I build an app rendering data from an external API. In development mode everything works fine but in production the API doesn't load. It does't return anything not error in console.
axios.get("https://api.github.com/repos/....")
.then(response => ...)
.catch(error => console.log(error))
axios.get("https://api.github.com/...")
.then(response => {
....
})
.catch(error => console.log(error))
Can anyone tell me what the problem is?

You should check the network tab in the console and see which response code that request is returning. The catch block will only be hit if the response code of that request is one of these client errors listed on this website: https://httpstatuses.com/

Full code here
Note In development mode.
My signup form work fine, login work fine
But in production none of this work!
I have google during for one week but dont find answer.
import React, {useState, useEffect} from 'react';
import axios from 'axios';
import ShowCase from './utils/table.github.user';
import Validator from "../mm-admin/auth/auth.validator"
const Homepage = () => {
const [organisations, setOrgnisations] = useState([])
const [searchContributor, setSearchContributor] = useState('');
const [searchContributorResult, setSearchContributorResult] = useState([]);
const [isAdded, setAdded] = useState(false);
useEffect(() => {
let cleanup = false;
requestApi()
return () => {
cleanup = true;
}
}, [searchContributor])
const requestApi = () =>{
axios.get("https://api.github.com/repos/git/git/contributors", {
params : {
rejectUnauthorized: false,//add when working with https sites
requestCert: false,//add when working with https sites
agent: false,//add when working with https sites
}
})
.then(response => {
const all = response.data;
const result = all.filter(contributor => {
return contributor.login.toLowerCase().includes(searchContributor.toLowerCase())
})
setSearchContributorResult(result)
})
.catch(error => console.log(error))
axios.get("https://api.github.com/organizations", {
params : {
rejectUnauthorized: false,//add when working with https sites
requestCert: false,//add when working with https sites
agent: false,//add when working with https sites
}
})
.then(response => {
const all = response.data;
const result = all.filter(contributor => {
return contributor.login.toLowerCase().includes(searchContributor.toLowerCase())
})
setOrgnisations(result)
})
.catch(error => console.log(error))
}
const makeSearchContr = event => {
event.preventDefault()
setSearchContributor(event.target.value)
}
const addFavorite = (favorite, notes) => event => {
event.preventDefault();
if (Validator.isAuthenticated()) {
const id = Validator.isAuthenticated().user._id;
const favorites = {
item : JSON.stringify(favorite),
note : notes
}
axios.put("/user/action/" + id, favorites)
.then(res => {
setAdded(true)
const timer = setTimeout(() => {
setAdded(false)
}, 4000)
return () => clearTimeout(timer)
})
.catch(error => console.log(error))
} else {
console.log("Need to loged")
}
}
const contributorGit = () => {
return searchContributorResult.map((contributor, index) => {
return <ShowCase key={index} item={contributor} status={isAdded} favorite={addFavorite}/>
})
}
const organisationsGit = () => {
return organisations.map((organisation, index) => {
return <ShowCase key={index} item={organisation} favorite={addFavorite}/>
})
}
return (
<article>
<div className="">
<div className="container">
<form>
<div className="">
</div>
<div className="form-group">
<input type="text" className="form-control" placeholder="Search" value={searchContributor} onChange={makeSearchContr}/>
</div>
</form>
</div>
</div>
<div className="github-user" id="github">
<div className="container">
<h2>List contributor :</h2>
<ul style={{paddingLeft : '0px'}}>
{contributorGit()}
</ul>
<h2>List organisation :</h2>
<ul style={{paddingLeft : '0px'}}>
{organisationsGit()}
</ul>
</div>
</div>
</article>
)
}
export default Homepage;

Related

Search function now working in React photo gallary

Working on a small application that takes a pexels api and displays photos dynamically. When I send the search request for my api to fectch based on the new params, it does actually update the page with new photos but not the ones based on the params. I though I got the search function correct, maybe it's cause I'm not using it in a useEffect? But if I did use it in a useEffect, I wouldn't be able to set it on the onClick handle. I tried to console.log the query I was getting from the onChange but it doesn't seem like it's getting the result. What am I doing wrong?
import { useState, useEffect } from 'react'
import pexelsApi from './components/pexelsApi'
import './App.css'
const App = () => {
const [images, setImages] = useState([]);
const [loading, setLoading] = useState(false);
const [nextPage, setNextPage] = useState(1);
const [perPage, setPerPage] = useState(25);
const [query, setQuery] = useState('');
const [error, setError] = useState('');
useEffect(() => {
const getImages = async () => {
setLoading(true);
await pexelsApi.get(`/v1/curated?page=${nextPage}&per_page=${perPage}`)
.then(res => {
setImages([...images, ...res.data.photos]);
setLoading(false);
}).catch(er => {
if (er.response) {
const error = er.response.status === 404 ? 'Page not found' : 'Something wrong has happened';
setError(error);
setLoading(false);
console.log(error);
}
});
}
getImages();
}, [nextPage, perPage]);
const handleLoadMoreClick = () => setNextPage(nextPage + 1)
const search = async (query) => {
setLoading(true);
await pexelsApi.get(`/v1/search?query=${query}&per_page=${perPage}`)
.then(res => {
setImages([...res.data.photos]);
console.log(res.data)
setLoading(false);
console.log(query)
})
}
if (!images) {
return <div>Loading</div>
}
return (
<>
<div>
<input type='text' onChange={(event) => setQuery(event.target.value)} />
<button onClick={search}>Search</button>
</div>
<div className='image-grid'>
{images.map((image) => <img key={image.id} src={image.src.original} alt={image.alt} />)}
</div>
<div className='load'>
{nextPage && <button onClick={handleLoadMoreClick}>Load More Photos</button>}
</div>
</>
)
};
export default App
import axios from 'axios';
export default axios.create({
baseURL: `https://api.pexels.com`,
headers: {
Authorization: process.env.REACT_APP_API_KEY
}
});
Your main issue is that you've set query as an argument to your search function but never pass anything. You can just remove the arg to have it use the query state instead but you'll then need to handle pagination...
// Helper functions
const getCuratedImages = () =>
pexelsApi.get("/v1/curated", {
params: {
page: nextPage,
per_page: perPage
}
}).then(r => r.data.photos)
const getSearchImages = (page = nextPage) =>
pexelsApi.get("/v1/search", {
params: {
query,
page,
per_page: perPage
}
}).then(r => r.data.photos)
// initial render effect
useEffect(() => {
setLoading(true)
getCuratedImages().then(photos => {
setImages(photos)
setLoading(false)
})
}, [])
// search onClick handler
const search = async () => {
setNextPage(1)
setLoading(true)
setImages(await getSearchImages(1)) // directly load page 1
setLoading(false)
}
// handle pagination parameter changes
useEffect(() => {
// only action for subsequent pages
if (nextPage > 1) {
setLoading(true)
const promise = query
? getSearchImages()
: getCuratedImages()
promise.then(photos => {
setImages([...images, ...photos])
setLoading(false)
})
}
}, [ nextPage ])
The reason I'm passing in page = 1 in the search function is because the setNextPage(1) won't have completed for that first page load.

How to add loader correctly while infinite scrolling?

I tried multiple ways to implement loading while fetching more data during infinite scrolling, but nothing worked properly, so I deleted loader; I have here state (with redux) named: loading but cannot write the logic of loading correctly. Could you please tell me how I can make it work?
Here I will provide with code:
import React, {useEffect} from 'react';
import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import {setAllUsers, setLoading, setPage} from '../redux/actions/actions';
import User from './User';
import '../styles/AllUsersList.css';
const AllUsersList = () => {
const allUsers = useSelector(state => state.setAllUsersReducer);
const page = useSelector(state => state.setPageReducer);
const loading = useSelector(state => state.setLoadingReducer);
const dispatch = useDispatch();
const fetchAllUsers = () => {
fetch(`${url}/${page}/15`)
.then(res => res.json())
.then(data => {
dispatch(setAllUsers(data.list));
})
.catch(err => console.log('Error message: ', err))
}
useEffect(() => {
fetchAllUsers();
}, [page])
const handleScroll = () => {
dispatch(setPage());
}
window.onscroll = function () {
if(window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight) {
handleScroll();
}
}
return (
<div className="allUsersList">
{
allUsers ? (
allUsers.map((user, index) => (
<Link key={user.id} to={`/user/${user.id}`}>
<User name={user.name} lastName={user.lastName} prefix={user.prefix} title={user.title} img={user.imageUrl}/>
</Link>
))
) : (
<div> Loading... </div>
)
}
</div>
)
}
export default AllUsersList;
Your state loading would be set to true in your function fetchAllUsers the data and when the promise resolves it gets set to false.
Here's an example on how you would do it, you can adapt it to use a redux dispatcher to change loading state.
const loading = useState(false);
...
const fetchAllUsers = () => {
setLoading(true);
fetch(`${url}/${page}/15`)
.then(res => res.json())
.then(data => {
dispatch(setAllUsers(data.list));
})
.catch(err => console.log('Error message: ', err))
.finally(() => {
setLoading(false);
})
}
...
{
!loading ? (
allUsers.map((user, index) => (
<Link key={user.id} to={`/user/${user.id}`}>
<User name={user.name} lastName={user.lastName} prefix={user.prefix} title={user.title} img={user.imageUrl}/>
</Link>
))
) : (
<div> Loading... </div>
)
}

How can I POST data using API from REACTJS?

This is my react code here I want to POST Data using postPoll API and update polls state but I am not understand how can do that.
please help..! please help..!please help..!please help..!please help..!please help..!please help..! at line number 33, 34 ( handalchange )
import React, { useState, useEffect } from "react";
import Poll from "react-polls";
import "../../styles.css";
import { isAutheticated } from "../../auth/helper/index";
import { getPolls, postPoll } from "../helper/coreapicalls";
import axios from "axios";
import { API } from "../../backend";
const MainPoll = () => {
const userId = isAutheticated() && isAutheticated().user._id;
const [polls, setPoll] = useState([]);
const [error, seterror] = useState(false);
useEffect(() => {
loadPoll();
}, []);
const loadPoll = () => {
getPolls().then((data) => {
if (data.error) {
seterror(data.error);
} else {
setPoll(data);
console.log(data);
}
});
};
// Handling user vote
// Increments the votes count of answer when the user votes
const handalchange = async (pollId, userId, answer) => {
console.log(pollId); // getting
console.log(userId); // getting
console.log(answer); // getting
await axios.post(`${API}/vote/${pollId}`, userId, answer);
// postPoll(pollId, { userId, vote }).then(() => {
// loadPoll();
// });
};
return (
<div className="">
<div className="container my-5">
<h1 className="blog_heading my-3">Poll's of the Day</h1>
<div className="row">
{polls.reverse().map((poll, index) => (
<div className="col-lg-4 col-12 poll_border" key={index}>
<Poll
noStorage
question={poll.question}
answers={Object.keys(poll.options).map((key) => {
return {
option: key,
votes: poll.options[key].length,
};
})}
onVote={
(answer) =>
handalchange(poll._id, userId, answer, console.log(answer)) // getting vote
}
className="mb-2"
/>
</div>
))}
</div>
</div>
</div>
);
};
export default MainPoll;
this is my frontend-
POSTMAN - request = >
and here is my backend API -
// post
export const postPoll = (pollId, post) => {
return fetch(`${API}/vote/${pollId}`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(post),
})
.then((response) => {
return response.json();
})
.catch((err) => console.log(err));
};
It depends on what object does onVote event from Poll component pass. But if it's vote object, that's required in postPoll method as second arguement, than:
function in onVote event should pass poll.id from this component and vote object from Vote component onVote event itself:
onVote={(vote) => handalchange(poll.id, vote)}
handalchange should fire postPoll api method with these arguements and load updated poll data on success:
const handalchange = (pollId, vote) => {
postPoll(pollId, vote).then(() => {
loadPoll();
});
}

.then promise not working within axios delete request in react application

I am trying to call a function to fetch data from the database upon deleting a note. This is so that the array of notes can be updated to reflect the deleted note. The function where the error occurs is called deleteNote and the function I am trying to call within the .then promise is getNotes.
Below is the code in my App.js file. If someone could help me solve this I'd greatly appreciate it.
import React, { useEffect, useState } from 'react';
import axios from 'axios';
// import HighlightOffIcon from '#material-ui/icons/HighlightOff';
import './App.css';
const App = () => {
const [note, setNote] = useState('');
const [notesList, setNotesList] = useState([]);
const getNotes = () => {
axios.get('http://localhost:8080/api')
.then((res) => setNotesList(res.data))
.catch(() => alert('Error recieving data.'));
}
useEffect(() => {
getNotes();
}, [])
const handleChange = (event) => {
const content = event.target.value;
setNote(content);
}
const handleSubmission = (event) => {
event.preventDefault();
axios({
url: 'http://localhost:8080/api/save',
method: 'POST',
data: {
content: note
}
})
.then((res) => {
console.log('Created Note');
setNote('');
getNotes();
})
.catch(() => {
console.log('Internal server error');
})
}
const deleteNote = (event) => {
const value = event.target.value;
axios({
method: 'DELETE',
url: 'http://localhost:8080/api/delete',
data: {
_id: value
}
})
.then(() => {
console.log('Note Deleted');
getNotes(); //Where the notes should be fetched upon successful deletion.
})
.catch(() => {
alert('Error deleting note.');
});
}
return (
<div className="app">
<h1>React Notes App</h1>
<form onSubmit={handleSubmission}>
<input
type="text"
placeholder="Enter note"
value={note}
onChange={handleChange}
/>
<button className="submit-button">Submit</button>
</form>
<div className="notes-list">
{notesList.map((note, index) => {
return (
<div className="note" key={index}>
<p>{note.content}</p>
<button value={note._id} className="delete-button" onClick={deleteNote}><i className="fas fa-trash-alt"></i></button>
</div>
);
})}
</div>
</div>
);
}
export default App;
I figured out the issue. When sending a request with axios, you must have a response sent back from the server in order to execute any code you may have in the promise.
example server code:
app.delete('/delete', (req, res) => {
BlogPost.delete({_id: req.body.id}, (err) => {
if (err) {
console.log(err);
} else {
console.log('Successfully deleted blog post.')
res.json({ //Must include a response to execute code within the axios promise.
msg: 'Delete request was recieved.'
});
}
});
});

ReactJs 'map' is Not a Function

I Try to make Github API fetch To get User GitHub info
componentDidMount() {
const { username } = this.props;
const { clientId, clientSecret, count, sort } = this.state;
fetch(
`http://api.github.com/users/${username}/repos?per_page=${count}&sort=${sort}&client_id=${clientId}&client_secret=${clientSecret}`
)
.then(res => res.json())
.then(data => {
if (this.refs.myRef) {
this.setState({ repos: data.conves });
}
})
.catch(err => console.log(err));
}
When I Start render it with map() I get an error that map() is not function!
const repoItems = repos.map(repo => (
<div>
<Link to={repo.html_url} className="text-info" target="_blank">
{repo.name}
</Link>
</div>
));
enter image description here

Categories

Resources