Reputation: 91969
I am trying to build RSS reader where there are a bunch of URLs and clicking on one of them loads the content for the selected content.
My attempt looks like
import React from "react";
import Listings from "./listings"
import Content from "./content"
const urls = [
"https://www.washingtonpost.com/news/the-switch/wp/2017/10/17/googles-pixel-2-gives-you-the-best-of-android-if-you-can-find-it/?utm_term=.dacb8f419a4b",
"https://arstechnica.com/gadgets/2017/10/windows-10-fall-creators-update-lots-of-small-changes-and-maybe-the-revolution/",
"https://www.theverge.com/2017/10/17/16481628/microsoft-surface-book-2-price-release-date-specs-availability-processor"
];
export default class RSS extends React.Component {
constructor(props) {
super(props)
this.state = {
selectedUrl: urls[0],
urls: urls,
content: "TBD"
}
}
onUrlSelect = (e, url) => {
e.preventDefault();
//console.log("selected Url Index: ", url);
this.setState({selectedUrl: url});
}
componentWillMount() {
this.loadData(this.state.selectedUrl);
}
loadData = (url) => {
fetch(url)
.then(function (response) {
console.log(url + " -> " + response.ok);
return response.body;
})
.then(function (data) {
console.log("data: ", data);
this.setState({ content: data });
}.bind(this))
.catch(function (err) {
console.log("failed to load ", url, err.stack);
});
}
render() {
return (
<div>
<Listings urls={this.state.urls} onUrlSelect={this.onUrlSelect}/>
<Content data={this.state.data}/>
</div>
)
}
}
Where Content
looks like
import React from "react";
export default function Content(props) {
return (
<div>
<p> Loading: {props.data} </p>
</div>
);
}
When I try to load it, Nothing prints out. However, on the Developer Tools > Console
, I see
data: ReadableStream {}locked: (...)__proto__: Object
index.js? [sm]:35
My code is available on https://codesandbox.io/s/wkwm8z3xl
I am not sure what I am doing wrong, any help is highly appreciated. Thanks
update
I changed my code to read response.text()
and then on the view
I did the following
export default function Content(props) {
return (
<div>
<div dangerouslySetInnerHTML={{__html: props.data}}/>
</div>
);
}
as recommended in https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
However, the page the results as output is not exactly how it should be
The code is updated at https://codesandbox.io/s/wkwm8z3xl
This is happening because the other assets like css
, images
are not fetched.
How can I fix this?
Upvotes: 2
Views: 26956
Reputation: 81
You should use response.text() method to reads content.
See https://developer.mozilla.org/en-US/docs/Web/API/Response
loadData = (url) => {
fetch(url)
.then(function (response) {
// console.log(url + " -> " + response.ok);
if(response.ok){
return response.text();
}
throw new Error('Error message.');
})
.then(function (data) {
console.log("data: ", data);
this.setState({ content: data });
}.bind(this))
.catch(function (err) {
console.log("failed to load ", url, err.message);
});
}
Upvotes: 0
Reputation: 85012
return response.body
This line doesn't actually give you the data in the body. To get access to the data in the body, you'll need to use one of a couple functions. It looks like the data you're getting back is just a text file, so you'll want to do return response.text()
. You can read more about extracting the body from Fetch here: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Body
One other thing you'll need to fix is that when you call setState, you're setting the data onto state.content
, but then in your render function you're expecting it to be on this.state.data
. One or the other will need to change.
Upvotes: 2