Parsing JSON in React Native fetch method doesnt work - api

Im trying to call an API with fetch from React Native App but itdoesnt log the response data (console.warn('data', data)) for some reason. It prints the 'call to getArtists' log but then nothing happens.
const URL = 'https://jsonplaceholder.typicode.com/posts'
function getArtists(){
console.log('call to getArtists')
return fetch(URL)
.then(response => response.json())
.then(data => {
console.warn('data', data)
})
}
Code is available here: https://snack.expo.io/rkzea2Zlm at components/api-client.js
What am I doing wrong?

First in your "api_client.js", put a return inside like the code bellow.
function getArtists(){
console.log('call to getArtists')
return fetch(URL)
.then(response => response.json())
.then(data => {
return data
})
}
In your App.js just do that inside componentWillMount.
componentDidMount(){
getArtists()
.then(data => {
alert(JSON.stringify(data))
});
}

Related

How to fetch an online array to a VueJs app

I have an online array online array link
that I want to add to my VueJs project I use this code:
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json())
.then((json) => console.log(json))
.then(json => {
this.lists = json.lists
})
from VueMastery at Vue.org but it doesn't work, gives me an error Json.lists isn't defined
Remove this line
then((json) => console.log(json))
You are returning console.log(json) it doesnt make sense
If you want still to log it do it like this
then(json => {
console.log(json);
return json;
})

React Native fetch doesn't work in another fetch callback

If I call my api function from POINT 1, fetch method inside the api method works well. When I comment it out and call the function at POINT 2 fetch method inside the addAccount() doesn't work. There is no exception, no rejection, no request on Reactotron, even I can't find request over Charles Proxy. What is the difference and what I have to know to figure it out?
I tried with RN 0.55.2 and 0.57.5
// Auth.js typical react native component
import * as api from '../actions/api';
class Auth extends Component {
// first triggered function
loginAccount(){
// api.addAccount(); // POINT 1 - this line works well if I uncomment
fetch('https://domain-a.com/login/',{
method: 'POST',
credentials: "same-origin",
headers: {
'accept-language': 'en-US;q=1',
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
body: encodeURIComponent(bodyParameters)
}).then((response) => {
console.log(response);
return response.json()
}).then(({ status, invalid_credentials }) => {
if(status == "ok"){
CookieManager.get('https://domain-a.com')
.then((cookies) => {
this.fetchAccountData(cookies);
})
})
}
fetchAccountData(cookies){
fetch('https://domain-a.com/'+cookies.user_id+'/info/',{
method: 'GET',
headers: {
'cookie': cookies
}
}).then((response) => {
return response.json();
})
.then(({ user, status }) => {
api.addAccount(); // POINT 2 - this line doesn't work
});
}
}
// api.js
// I repleaced fetch code with document example just to be clearify
export const addAccount = () => {
console.log("fetch begin"); // always works
fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson); // won't works from point 2
})
.catch((error) =>{
console.error(error); // never runs
});
}
It looks like your first .then statement in the addAccount() function is missing a return statement. responseJson would be undefined without a proper a 'return response.json()' statement. Also adding brackets for better semantic formatting.
export const addAccount = () => {
console.log("fetch begin"); // always works
fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => {
console.log(response); //test this response
return response.json();
})
.then((responseJson) => {
console.log(responseJson); // won't works from point 2
})
.catch((error) =>{
console.error(error); // never runs
});
}

Fetch someUrl.html not working in React Native / Expo?

I'm trying to use fetch to get the contents of the HTML page in React Native, and I'm running it on expo, here:
https://snack.expo.io/#abalja/hellofetch
Basically the code is nothing special, uses 'fetch' which does work for loading .json files, but I can't get it to work for .html files. It just silently fails, and I don't even get an error logged. I'm not sure if this is Expo or ReactNative issue.
const url2 = 'http://www.spiegel.de/sport/fussball/nations-league-italien-trifft-in-der-nachspielzeit-polen-steigt-ab-a-1233219.html#ref=rss'
export default class App extends React.Component {
componentDidMount(){
console.log('did mount, fetching: ' + url2)
fetch(url2)
.then((response) => {
console.log(response) // 1
return response.text()
})
.then((responseText) => {
console.log('fetch text', responseText) // 2
// return responseText.movies;
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View style={styles.container}>
</View>
);
}
}
At 1 I get the response logged:
{type:"default",status:200,ok:true,headers:{…},url:"http://www.spiegel.de/sport/fussball/nations-league-italien-trifft-in-der-nachspielzeit-polen-steigt-ab-a-1233219.html",_bodyInit:{…},_bodyBlob:{…}}
type:"default"
status:200
ok:true
►headers:{map:{…}}
url:"http://www.spiegel.de/sport/fussball/nations-league-italien-trifft-in-der-nachspielzeit-polen-steigt-ab-a-1233219.html"
►_bodyInit:{_data:{…}}
►_bodyBlob:{_data:{…}}
At 2 I get absolutely nothing logged.
Promise syntax is confusing to me, so I changed into async-await:
async componentDidMount() {
console.log('did mount, fetching: ' + url2);
try {
let response = await fetch(url2);
let text = await response.text();
console.log(text)
} catch(e) {
console.log(e)
}
}
It works! You can check it here: https://snack.expo.io/#aazwar/fetch-url
It's because you are parsing your Response as text and not as json, and then trying to call object-key against string. Basically what you have at that point is string which looks like json. Parse your response with .json()-method instead.
return response.text() should be therefore return response.json()
to reconstruct your code
// With .then()
fetch(url2)
.then((response) => {
return response.json()
})
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
// OR with await/async
const response = await fetch(url2)
const json = await response.json() // As '.json()' is async function as well
return json.movies
I would succest using await/async since syntax is much more cleaner and it start's to be way to go.

using fetch with ES2015 modules in Canary

I'm trying out ES2015 modules in Chrome Canary Version 60.0.3102.0. My script.js file reads like this:
import {fetchJSON} from './functions/fetchJSON.js';
const configFile = 'config.json';
const init = () => {
fetchJSON(configFile)
.then((data) => { // code fails here at ln.7
console.log(data);
})
.catch(error => console.log(error));
};
init();
and my fetchJSON.js file reads like this:
export function fetchJSON(url) {
const fetchJSON = fetch(url)
.then(response => response.json())
.then(data => {
console.log(data); // data exists and is reported in the console
return data;
});
}
I'm getting the error:
script.js:7 Uncaught TypeError: Cannot read property 'then' of undefined
at init (script.js:7)
at script.js:14
Your fetchJSON function isn't returning anything. Because of that, when you try chaining a .then on the result of fetchJSON, you're getting the Uncaught TypeError - undefined.
Solution: return your Promise chain in your fetchJSON function:
export function fetchJSON(url) {
return fetch(url)
.then(response => response.json())
.then(data => {
return data;
});
}

Fetch API get raw value from Response

I use React-Native request some data, here is my code:
fetch('https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json')
.then((response)=>{
return response.json()
})
.then((responseJSON)=>{
callback(responseJSON)
})
.catch((error)=>{
console.error(error);
})
.done()
I see the response is a Response object, and the json function code is return this.text().then(JSON.parse), I'm confused that what is the parameter of theJSON.parse? Is that the response raw value? How can I get it?
Here's how you'd do what you want. In my case I wanted to manually parse the JSON because a certain character (\u001e) is improperly parsed by the in-built JSON parser.
Change from:
fetch(url)
.then(response => response.json())
.then((data) => {
data....
to:
fetch(url)
.then(response => response.text())
.then((dataStr) => {
let data = JSON.parse(dataStr);
data...