React-Native render json from fetch - json

I have a fetch returning on ComponentDidMount(). Trying to get the response to render on the page.
I have set the state as follows:
this.state = {
loading: true,
file: null,
video: null,
marks: []
};
and my fetch:
componentDidMount() {
return fetch('http://10.0.2.2:8080/marks/createMark')
.then(response => response.json())
.then((data) => {
this.setState({
loading: false,
marks: data.mark
}, () => {
console.log(data.mark);
console.log(this.state.marks);
// const dataMap = data.mark.map((item) => {
// return {
// key: item.id,
// label: item.mark
// };
// });
});
})
.catch(err => console.log(err));
}
Now my render inside of the return:
const { marks } = this.state;
<FlatList
data={marks}
renderItem={({ item }) => <Text>{item.mark}</Text>}
keyExtractor={(item, index) => index}
/>
Do I have to map the data then try to render it??
OUTPUT OF console.log(this.state.marks):
{ _id: '5b61e47a55a0000aa980fab1', mark: 'ItHe', __v: 0 }
The mark is a pseudorandom string that can contain letters and numbers created on the backend

As this.state.marks is an object. First, you need to convert it to this form [{}]. You can do the following changes to make it work.
fetch('http://10.0.2.2:8080/marks/createMark')
.then(response => response.json())
.then((data) => {
let marks = [data.mark]; //Add this line
this.setState({
loading: false,
marks: marks // Change this line
}, () => {
....
Rest of your code

marks is an array but you're not sharing what each object in the array looks like. If it's an array of strings, you're good but if it's an object, you'll need to destructure it and pull out the string you're looking to render.
<Text>{item.mark.someKeyWhoseValueIsAString}</Text

Related

How to randomly fetch from a JSON file and render it into a FlatList?

I have an app which fetch data from a JSON file. The problem is, it fetches the data from top to bottom. I want it to fetches randomly within the JSON file. How would I achieve this?
This is how I fetch the JSON:
componentDidMount() {
const url = ''
this.setState({ isLoading: true });
fetch(url)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
dataSource: responseJson.product,
dataBackup: responseJson.product,
isLoading: false
});
})
.catch((error) => {
console.log(error)
})
}
When you're reading a file there is no way to change the order of content.
However, once the json is parsed, since your product key is an array, you can shuffle this array when you setting the state.
You can use the shuffle function from this answer
How to randomize (shuffle) a JavaScript array?
Alternatively if you're using lodash, there is shuffle function for collections :
https://lodash.com/docs/4.17.14#shuffle
Your final code would be:
// import shuffle function from linked anwser,
// or with lodash :
import { shuffle } from "lodash";
// ...
componentDidMount() {
const url = "";
this.setState({ isLoading: true });
fetch(url)
.then(response => response.json())
.then(responseJson => {
this.setState({
dataSource: shuffle(responseJson.product),
dataBackup: responseJson.product,
isLoading: false
});
})
.catch(error => {
console.log(error);
});
}

Cannot get any rate's value

I am trying to load the data from exchangeratesapi but some how I cannot load the exchangerates's data!!
componentDidMount() {
this.setState({loading: true})
fetch("https://api.exchangeratesapi.io/latest")
.then(response => response.json())
.then(data => {
console.log(data)
this.setState({
loading: false,
currency: data,
})
})
}
render() {
var text = this.state.loading ? "loading..." : this.state.currency.BGN
return (
<div>
<p>{this.state.currency.RON}</p>
</div>
)
}
I have try on of the dumbest way to load the data.
omponentDidMount() {
this.setState({loading: true})
fetch("https://api.exchangeratesapi.io/latest")
.then(response => response.json())
.then(data => {
console.log(data)
this.setState({
loading: false,
currency: data,
bulgaria:data.rates.BGN,
})
})
}
And inside of render
var text = this.state.loading ? "loading..." : this.state.currency.bulgaria
But I believe there got a to be a better way to do this.
You are trying to access the property directly from currency however, it exists in rates.
This is incorrect:
{this.state.currency.RON}
It should be:
{this.state.currency.rates.RON}
Similarly, the variable text you created is not used anywhere. IMHO it should be like this:
render() {
const {loading, currency} = this.state;
console.log(currency); //only for debugging
return (
{ loading? 'Loading...' : (
<div>
<p>{currency.rates.RON}</p>
</div>)
}
)
}

How to get the length of the response from a fetch request?

I have got series of data that contains some objects in one array(json file) and it will be shown by react.
Here is my code:
class App extends React.Component {
constructor(props){
super(props);
this.state = {
data: [],
library:null,
perPage: 20,
currentPage: 1,
maxPage: null,
filter: ""
};
}
componentDidMount() {
fetch('/json.bc')
// Here I want to get the length of my respose
.then(response => response.text())
.then(text => {
var Maindata = JSON.parse(text.replace(/\'/g, '"'))
this.setState(state => ({
...state,
data: Maindata
}), () => {
this.reorganiseLibrary()
})
}).catch(error => console.error(error))
}
reorganiseLibrary = () => {
const { filter, perPage , data } = this.state;
let library = data;
if (filter !== "") {
library = library.filter(item =>
item.hotelinfo.hotelsearch.realname.toLowerCase().includes(filter)
);
}
library = _.chunk(library, perPage);
this.setState({
library,
currentPage: 1,
maxPage: library.length === 0 ? 1 : library.length
});
};
// Previous Page
previousPage = () =>
this.setState(prevState => ({
currentPage: prevState.currentPage - 1
}));
// Next Page
nextPage = () =>
this.setState(prevState => ({
currentPage: prevState.currentPage + 1
}));
// handle filter
handleFilter = evt =>
this.setState(
{
filter: evt.target.value.toLowerCase()
},
() => {
this.reorganiseLibrary();
}
);
// handle per page
handlePerPage = (evt) =>
this.setState({
perPage: evt.target.value
}, () => this.reorganiseLibrary());
// handle render of library
renderLibrary = () => {
const { library, currentPage } = this.state;
if (!library || (library && library.length === 0)) {
return <div class="tltnodata">no result!</div>;
}
return library[currentPage - 1].map((item, i) => (
<input type="hidden" value={item.hotelinfo.hotelsearch.hotelid} name="hotelid"/>
));
};
render() {
const { library, currentPage, perPage, maxPage } = this.state;
return (
<div className="Main-wrapper">
<div class="filter_hotelname"><input value={this.state.filter} onChange={this.handleFilter} class="hotelName" /></div>
<div class="countHotel"> <span class="numbersearch"></span> // Here I want two show the count of items </div>
<div className="wrapper-data">
{this.renderLibrary()}
</div>
<div id="page-numbers">
<div class="nexprev">
{currentPage !== 1 && (
<button onClick={this.previousPage}><span class="fa-backward"></span></button>
)}
</div>
<div className="data_page-info">
{this.state.currentPage} از {this.state.maxPage}
</div>
<div class="nexprev">
{(currentPage < maxPage) && (
<button onClick={this.nextPage}><span class="fa-forward"></span></button>
)}
</div>
</div>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('Result'));
I want to find the length of response from a request with fetch. Also I want to know how to find the count of items that will be shown by renderLibrary . For example in json.bc we have 4 objects I want to show 4 in numbersearch span.
Using Fetch API you can find json response item length by running below code snippet. I have also added comment in code as well.
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => {
//below method return promise based response by converting stream object to json
return response.json();
}).then(json => {
//Once succcessful callback return you can find length of number of item
console.log(json);
alert("Number of item:"+json.length)
})
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => {
//below method return promise based response by converting stream object to json
return response.json();
}).then(json => {
//Once succcessful callback return you can find length of number of item
alert(json.length)
})
You can use the length of the data array from the state to distinguish the number of items.
Since arrays start at 0, you will need to increment the count by one. Here's an example snippet below that you can use in your code sample.
<div class="countHotel"><span class="numbersearch">{this.state.data && this.state.data.length + 1}</span></div>

How to add a state into a api fetch()

Hi I need to add a state into my API fetch but struggling to see why it works when the state is an empty string but does not work if there is a string inside the state please view the examples
The idea is the user enters new text in an input which updates the state Search and then updates fetch url so they can search the database
Example Working Code (Notice the state Search is empty)
export default class ThirdScreen extends React.Component {
state = {
search: '',
image: ''
}
componentDidMount() {
this.fetchsa();
}
fetchsa = () => {
const {search} = this.state;
fetch(`https://xxx/search?q=moon&media_type=image`)
.then((response) => response.json())
.then((result) => this.setState({
image: result.collection.items[0].links[0].href
}))
}
Example not working Code
export default class ThirdScreen extends React.Component {
state = {
search: 'moon', //Notice this is not empty and now causes an error
image: ''
}
componentDidMount() {
this.fetchsa();
}
fetchsa = () => {
const {search} = this.state;
fetch(`https://xxx/search?q='${search}'&media_type=image`)
.then((response) => response.json())
.then((result) => this.setState({
image: result.collection.items[0].links[0].href
}))
}
The problem are the single quotes in your fetch URL:
const search = 'moon';
fetch(`https://xxx/search?q='${search}'&media_type=image`)
is NOT the same as
fetch(`https://xxx/search?q=moon&media_type=image`)
The API request goes through for 'moon' instead of moon and no results are found.
However this is ok:
fetch(`https://xxx/search?q=${search}&media_type=image`)
So:
Lose the single quotes around ${search}.
Handle an empty items array when no results are found.
For example:
fetch(`https://xxx/search?q=${search}&media_type=image`)
.then((response) => response.json())
.then((result) => result.collection.items.length > 0 && this.setState({
image: result.collection.items[0].links[0].href
}))
Try this:
export default class ThirdScreen extends React.Component {
state = {
search: 'moon', //Notice this is not empty and now causes an error
image: ''
}
componentDidMount() {
this.fetchsa();
}
fetchsa = () => {
const {search} = this.state;
fetch(`https://xxx/search?q='${search}'&media_type=image`)
.then((response) => response.json())
.then((result) => this.setState({
result.collection && result.collection.items[0] && result.collection.items[0].links[0] ?image: result.collection.items[0].links[0].href:null
}))
}

Adding an Audio object to my react state array

componentWillMount() {
console.log('Component WILL MOUNT!')
axios.get('/channels').then( (res) => {
console.log(res.data.data.playList);
this.setState({
categories: res.data.data.playList,
audioList: res.data.data.playList.url
})
}).catch( (err) => {
console.log(err);
});
}
In my componentWillMount() I get bunch of mp3 urls from a database and stores into a state called audioList so it has a bunch of URLs of a sound file. However, what I actually want to store is an Audio object (HTML5 Audio).
Usually, to make it playable, I would have to make a new Audio object like
this.audio = new Audio([URL]);
then do
this.audio.play()
Since I want to make a list of music, I would like to but everything like
this.state.audioList = [ audioObject1, audioObject2, audioObject3, ... ]
How can I do this?
EDIT
componentWillMount() {
console.log('Component WILL MOUNT!')
let playLists = [];
axios.get('/channels').then( (res) => {
//console.log(res.data.data.playList);
res.data.data.playList.map((value, key) => playLists.push(new Audio(value.url)));
this.setState((prevState) => {
return { audioList: playLists}
}, () => console.log("dddd" + this.state.audioList));
}).catch( (err) => {
console.log(err);
});
}
This gives me
EDIT2
componentWillMount() {
console.log('Component WILL MOUNT!')
let playLists = [];
axios.get('/channels').then( (res) => {
//console.log(res.data.data.playList);
res.data.data.playList.map((value, key) => playLists.push(new Audio(value.url)));
this.setState((prevState) => {
return { audioList: playLists, categories: res.data.data.playList}
});
}).catch( (err) => {
console.log(err);
});
}
You can try with array push like below for objects available inside array,
let playlists = [];
res.data.data.playList.map((value, key) => playlists.push(new Audio(value.url)));
this.setState((prevState) => {
return { audioList: playlists}
}, () => console.log(this.state.audioList));