Accessing axios body parameter outside the URL - javascript

I have this axios request:
axios.all([
axios.post(baseURL+'sentiments', {
sentiment_type: 'positive',
filter_tab: type
}),
axios.post(baseURL+'sentiments', {
sentiment_type: 'negative',
filter_tab: type
})
])
.then(axios.spread(result1, result2) => {
console.log(result1),
console.log(result2)
})
.catch(err => {
console.log(err)
})
Then in my render method,
What I am trying to achieve is to access 'sentiment_type' value 'positive' into some variable or something, to further use it for conditional rendering.
if(sentiment_type === positive){
then do this
}
else{
do something else
}
Is there any way to do this? Please guide.

I assume this part of code, is part of a component.
You could store these variables in a local store.
Here is a link for more information: State and Lifecycle
and an example, I hope this will help you.
class parentComponent extends React.Component {
state = {
sentiment_types: [];
}
componentDidMount() {
axios.post(baseURL+'sentiments', {
sentiment_type: 'positive',
filter_tab: type
})
.then((firstResponse) => {
axios.post(baseURL+'sentiments', {
sentiment_type: 'negative',
filter_tab: type
})
.then((secondResponse) => {
// Here you can store you results into the state
this.setState({
sentiment_types: ['positive', 'negative'];
})
})
.catch(err => {
console.log(err);
})
console.log(result)
})
.catch(err => {
console.log(err)
})
}
render() {
<childComponent sentiment_types={this.state.sentiment_types} />
}
}
const childComponent = (props) => {
if(props.state.sentiment_types.includes('positive')){
return <h1>oke</h1>
}
}

Related

Fetching with parameters in Javascript

As a quick summary, im trying to fetch from a URL and do so with 2 parameters.
I have no experience with javascript so i was trying this:
componentDidMount() {
$input = array("team" => {teamName}, "name" => {userPrincipalName});
fetch("http://localhost/openims/json.php?function=getDocuments&input=".urlencode(json_encode($input)))
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
files: result.files
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
This however does not seem to work. So my question would be: how do i succesfully pass the teamName and userPrincipalName from the context to the json_encode.
There is however 1 more problem with my code. I currently have two componentDidMounts, which are both using setState. The problem seems to be that whatever setState happens last, is the one that is being worked with, while the first setState is being completely overwritten. But i do need to do both the context setState AND the fetch to achieve my goal.
Here is my full code to give as clear an image as possible of what im doing:
import React from 'react';
import './App.css';
import * as microsoftTeams from "#microsoft/teams-js";
class Tab extends React.Component {
constructor(props){
super(props)
this.state = {
context: {}
}
}
componentDidMount(){
microsoftTeams.getContext((context, error) => {
this.setState({
context: context
});
});
}
componentDidMount() {
$input = array("team" => {teamName}, "name" => {userPrincipalName});
fetch("http://localhost/openims/json.php?function=getDocuments&input=".urlencode(json_encode($input)))
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
files: result.files
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { teamName, userPrincipalName } = this.state.context;
const { error, isLoaded, files } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{files.map(file => (
<li key={file.id}>
{file.name} {file.type}
<span id="user">Team: {teamName}, userPrincipalName: {userPrincipalName }</span>
</li>
))}
</ul>
);
}
}
}
export default Tab;
TL;DR
How do i use setState two times without problems? and how do i work the parameters teamName and userPrincipalName into my fetch?
Thank you!
If I understand correctly, what you need is backticks:
`http://localhost/openims/json.php?function=getDocuments&input=${userPrincipalName}`

Correct way to fetch through array

In the below compoenent, the function is neverending. Can someone tell me what to fix so that in the end the beers array in the state has 5 names?
export default class GetBeers extends React.Component {
constructor() {
super();
this.state = {
beers: [],
didError: false
};
this.getBeerInfo = this.getBeerInfo.bind(this);
}
render() {
return (
...
}
getBeerInfo() {
let beerArr = [1,2,3,4,5];
this.props.beerArr.map(id => {
fetch(`https://api.punkapi.com/v2/beers/${id}`)
.then(res => res.json())
.then(json => {
this.setState(state => {
const beers = state.beers.concat(json[0].name);
return {
beers
};
});
})
.catch(err => {
this.setState({
didError : true
});
});
})
}
}
Well your code should be somethings like this ..
import React from 'react';
export default class GetBeers extends React.Component {
constructor() {
super();
this.state = {
beers: [],
didError: false
};
this.getBeerInfo = this.getBeerInfo.bind(this);
}
render() {
return (
<div>{this.state.beers}</div>
)
}
componentDidMount() {
this.getBeerInfo()
}
getBeerInfo() {
let beerArr = [1,2,3,4,5];
beerArr.map(id => {
fetch(`https://api.punkapi.com/v2/beers/${id}`)
.then(res => res.json())
.then(json => {
this.setState({
//const beers = state.beers.concat(json[0].name);
//return {
//beers
//};
beers: this.state.beers.concat(json[0].name)
});
console.log('well at least this works')
})
.catch(err => {
this.setState({
didError : true
});
});
})
}
}
It is advised that you use the componentDidMount() lifecycle method for the fetch api and add what #atahnksy said.
When you are using setState, you can try this:
this.setState({ beers: [...this.state.beers, json[0].name])
This might fix your problem.
You can improve the render method using a combination of ternary operator(to display appropriate message when it cannot reach the server), format with map and ordered list to get something like this :
render() {
return (
<div><ol>{this.state.beers.length!==0 ? this.state.beers.map((beer)=><li>{beer}</li>) :"Could not retrieve any bears. Try again/ensure you can access the server/networtk"}</ol></div>
)
}

Fetch the first element from the array with fake api 'myjson.com'

In the 'myjson.com' website, I created a url 'https://api.myjson.com/bins/17qwmf' which returns an array to me. How to get an element with 'id: 1', the first element from the array. I'm trying to do it this way: 'https://api.myjson.com/bins/17qwmf/1' but I'm getting an error.
From the documentation it looks like it can be done: http://myjson.com/api
Code here: stackblitz demo
class Items extends Component {
constructor (props) {
super(props);
this.state = {
items: []
}
}
componentDidMount() {
const id = 1;
axios.get
axios({
url: `https://api.myjson.com/bins/17qwmf/${id}`,
method: "GET"
})
.then(response => {
console.log(response.data);
this.setState({
items: response.data
});
})
.catch(error => {
console.log(error);
})
}
render () {
return (
<div >
</div>
)
}
}
if there is no a router for getting an element by it id, you have to filter got array
class Items extends Component {
constructor (props) {
super(props);
this.state = {
items: []
}
}
componentDidMount() {
const id = 1;
axios.get
axios({
url: `https://api.myjson.com/bins/17qwmf`,
method: "GET"
})
.then(response => {
console.log(response.data);
this.setState({
items: response.data.filter(item => item.id === id)[0] // you will get a first element of got array
});
})
.catch(error => {
console.log(error);
})
}
render () {
return (
<div >
</div>
)
}
}
Please check this `https://api.myjson.com/bins/17qwmf?id=${id} if you want to fetch only element with id that ur passed

State array does not render properly in React.js

I am working on a hacker news clone I am trying to get the ids of the top stories from their api using axios in componentDidMount and then making another axios call to get the stories and push them in a state array but when I try to map over and render that array nothing shows up
class App extends Component {
constructor(props) {
super(props);
this.state = {
posts: []
}
}
componentDidMount() {
axios.get('https://hacker-news.firebaseio.com/v0/topstories.json')
.then( result => {
result.data.slice(0, 10).forEach(element => {
axios.get('https://hacker-news.firebaseio.com/v0/item/' + element + '.json')
.then( value => {
this.state.posts.push(value)
})
.catch(err =>{
console.log(err)
})
})
})
.catch(err => {
console.log(err);
})
}
render() {
return (
<div>
<Header title="Hacker News" />
{this.state.posts.map( (element, index) => <Post key={element.data.id} serialNum={index} postTitle={element.data.title} postVotes={element.data.score} postAuthor={element.data.by} />) }
</div>
)
}
}
Try setting the state like this:
axios.get('https://hacker-news.firebaseio.com/v0/item/' + element + '.json')
.then( value => {
this.setState({
posts: [value, ...this.state.posts]
})
})
.catch(err =>{
console.log(err)
})
})
This way you're using setState and appending every new value to the existing state.
As stated in the comments, don't use push for set state. In your code when you make the second request you must change the setState method to spread out the new value.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
posts: []
}
}
componentDidMount() {
axios.get('https://hacker-news.firebaseio.com/v0/topstories.json')
.then( result => {
result.data.slice(0, 10).forEach(element => {
axios.get('https://hacker-news.firebaseio.com/v0/item/' + element + '.json')
.then( value => {
this.setState(prevState => ({posts: [ value.data, ...prevState.posts]}))
})
.catch(err =>{
console.log("err");
console.log(err);
})
})
})
.catch(err => {
console.log(err);
})
}
render() {
return (
<div>
{this.state.posts && this.state.posts.map( (element, index) =>
<div key={element.id}>
{element.title}
</div>
)}
</div>
);
}
}
componentDidMount() is called after Render() only once. React doesn't know about the state changes unless you use setState().
componentDidMount() {
axios.get('https://hacker-news.firebaseio.com/v0/topstories.json')
.then( result => {
result.data.slice(0, 10).forEach(element => {
axios.get('https://hacker-news.firebaseio.com/v0/item/' + element + '.json')
.then( value => {
this.setState({posts: [value, ...this.state.posts]})
})
})
})
}
Use this.setState({posts : [value, ...this.state.posts]}) instead of this.state.posts.push(value). using ... (spread operator) appends the value to the original posts array.

Trouble Setting State in React

I'm calling an API (in Node) from my react component (Stats.js)
This function getName is taking a passed in prop (called 'value')
in order to look up a value in MongoDB. See code below:
/* Stats React Component --Stats.js*/
class Stats extends Component {
constructor(props) {
super(props);
this.state = {
marketdata: [],
value: '',
name: ''
}
}
componentDidMount() {
const {value, name} = this.state;
this.getName(value);
this.getData(name);
}
getName = (value=this.props.value) => {
value = value.replace(/"/g,"");
console.log('Value', value);
fetch(`/stats?ticker=${value}`)
.then(res => console.log('Response', res))
.then(results => {
this.setState({
name: results,
})
})
}
componentWillReceiveProps(nextProps) {
this.setState({value: nextProps.value });
}
getData = (name=this.state.name) => {
fetch(`https://api.coinmarketcap.com/v1/ticker/${name}/?convert=USD`)
.then(res => res.json())
.then(results => {
this.setState({
marketdata: results,
})
})
render() {
const {marketdata} = this.state;
return (
<div className="App">
{marketdata.map(data =>
<div key={data.id}>
<span>Price: {numeral(data.price_usd).format('$0.00')} </span>
<span>24 Hour Volume: {numeral(data["24h_volume_usd"]).format('$0.0a')} </span>
<span>Pct Change (24 Hrs): {(numeral((data.percent_change_24h)/100).format('0.0%'))} </span>
<span>Market Cap: {numeral(data.market_cap_usd).format('$0.0a')}</span>
</div>
)}
</div>
);
}
}
export default Stats;
As an example, this passed in prop (value) looks like this "BTC"--i can verify in developer console that the value of state is working correctly
I'm trying to set the state of the 'name' variable to the data returned from
the API lookup, the method called getName.
I can also verify in express that the data is being retrieved correctly on the backend. This is my express file that is called by getName
/* GET coin stats. stats.js */
router.get('/', (req, res, next) => {
let ticker = req.query.ticker;
console.log(ticker);
Stat.findOne({symbol:ticker})
.then(function(result) {
var stats = result;
console.log(stats.name);
res.json(stats.name);
})
.catch(function(err) {
console.log('caught error', err.stack)
res.send({ error: err })
})
});
Note my data in the database looks like this: symbol: "BTC", name: "Bitcoin", thus when a user enters BTC i need name to set state to 'Bitcoin"
If I do a http://localhost:3001/stats?ticker=BTC is does indeed return "Bitcoin"
However for some reason the state of 'name' is not changing when a user inputs a value and my Stats.js component receives a new value.
Anyone see any problems here?
getName and getData are only called, in componentDidMount which is called only once.
You need to call them when you update the value in componentDidUpdate too, when the state updates with the new value from componentWillReceiveProps function. Also provide a check in componentWillReceiveProps function before setting state
componentWillReceiveProps(nextProps) {
if(this.props.value !== nextProps.value) {
this.setState({value: nextProps.value });
}
}
componentDidMount() {
const {value, name} = this.state;
this.getName(value);
this.getData(name);
}
componentDidUpdate(prevProps, prevState) {
if(this.state.value !== prevState.value) {
this.getName(this.state.value);
}
if(this.state.name !== prevState.name) {
this.getData(this.state.name);
}
}

Categories