Convert ReadableStream to a String and then back to a ReadableStream - javascript

I am using the fetch api to get some data. At a more general point, I want to add data to all responses. So I want to parse the body of an Response object, add the data and rebuild an Response Object, that has again a ReadableStream in its body.
something like this:
fetch(url)
.then(response => {
var cpyResponse = response.clone();
console.log(cpyResponse.text());
return response.blob()
}
)
.then(blob => { return new Response(blob) })
.then(response => {
var cpyResponse = response.clone();
console.log(cpyResponse.text());
return response;
}
)
this somehow does not work. The second response is broken.

Related

Not getitng the same response in postman and fetch

I have this function to make a request to gyphy api
const getGifs = async () => {
const url = 'https://api.giphy.com/v1/gifs/search?api_key=mykey&q=ps5&limit=5';
const resp = await fetch(url)
.then(response => console.log(response));
}
In postman I get a json with the searched data but in javascript I get a response object, how can I get the searched data?
The fetch API does not return the raw response a such. The object you're getting is one that can be transformed into what you need. Since you're expecting JSON data, then your code should be:
const getGifs = async () => {
const url = 'https://api.giphy.com/v1/gifs/search?api_key=mykey&q=ps5&limit=5';
const resp = await fetch(url)
.then(response => response.json())
.then(jsonData => console.log(jsonData)) // the response you're expecting
}
The .json() method returns a Promise that resolves with your JSON parsed data.
According to the giphy api doc, the search endpoint returns a data element, which is an array of gifs. Just inspect your response object and see if it has a data element, then log response.data, not the full response
.then(response => console.log(response.data));
you are returning undefined because you are returning console.log() which is not right. Change it to response.body()
const fetch = require("node-fetch")
const getGifs = () => {
const url = 'https://api.giphy.com/v1/gifs/search?api_key=mykey&q=ps5&limit=5';
const resp =fetch(url)
.then(response => response.data);
return resp;
}
console.log(getGifs());

No response returned from fetch

I am trying to get data from the API and it doesnot return any value. I have tried to put the apiUrl in the browser directly it works there. Even a get request via postman returns request.
fetch(apiUrl)
.then((response) => {
let data = JSON.parse(response)
console.log(data)
return data;
})
Also in Chrome debugger, there is no request in the network tab as well. I have used the same code earlier to get the response.
Calling the API with Fetch gives a promise, and converting it to JSON will return yet another promise, which you need to "await" for again. This is how it should look like
fetch(URL)
.then(response => response.json())
.then(json => console.log(json))
fetch(apiUrl)
.then((response) => {
return response.json().then( res => {
let data = res;
console.log(data)
return data;
})
})
try this

retrieving json data by a key

const username = 'merMan';
fetch("./datz.json")
.then(response => response.text())
.then((response) => {
console.log(response);
})
my data response looks like below, still having a difficult time simply getting a user specific data. My response data outputs like below. I have tried using find, but always returns find is not a function, response[username] does not work either.
[{"mermAn":{"baseMapId":"459cc334740944d38580455a0a777a24","customBaseMap":"","zoomn":"5","orient":"0","centLon":"-93.69999999999843","centLat":"38.64999999999935"},
{"catWoman":{"baseMapId":"459cc334740944d38580455a0a777a24","customBaseMap":"","zoomn":"5","orient":"0","centLon":"-93.69999999999843","centLat":"38.64999999999935"},
{"Riddler":{"baseMapId":"459cc334740944d38580455a0a777a24","customBaseMap":"","zoomn":"5","orient":"0","centLon":"-93.69999999999843","centLat":"38.64999999999935"}}]
You need to parse the response after response.text(), like:
fetch("./datz.json")
.then(response => response.text())
.then((response) => {
try {
const parsedArray = JSON.parse(response);
console.log(parsedArray);
} catch (error) {
// response could not be parsed
}
})
Use .json() instead of .text()
const username = 'merMan';
fetch("./datz.json")
.then(response => response.json())
.then((users) => {
console.log(users.find(x => typeof x[username] !== "undefined"));
})

Fetch res.json() Attempt to invoke intergace method 'java.lang.String...'

I'm trying to convert a response from fetch function into json format but when I do so I get an error Attempt to invoke interface method 'java.lang.string com.facebook.react.bridge.ReadableMap.getString(java.lang.String)' on a null object reference.
Here is my code snippet with fetch function:
export const fetchAllUsers = () => {
fetch('http://192.168.1.103:3000/api/userData')
.then(res => {
res.json();
//console.warn('res keys = ' + Object.keys(res))
})
}
If comment back the row with console.warn I see the following "res keys = type, status, ok, statusText, headers, url, _bodyInit, _bodyBlod, bodyUsed".
bodyUsed = false
status = 200
type = default
Why I can't convert a response into json format? Or is there any another way to do so?
UPDATE
I've added the second then but I still get the error and the console.warn('res is json') is not running:
export const fetchAllUsers = () => {
fetch('http://192.168.1.103:3000/api/userData')
.then(res => {
res.json();
//console.warn('res keys = ' + Object.keys(res));
})
.then(res => {
console.warn('res is json');
console.warn(res);
})
}
UPDATE_2
I've run fetch function with another url but still got the problem. It seems like .json() causes the error. When I'm trying to console the result of fetch in the first .then() I get json object with type, status etc keys.
export const fetchAllUsers = () => {
fetch(`http://${localIP}:${port}/api/userData`)
//.then(res => res.json())
.then(json => console.warn('JSON: ' + json))
.catch(e => console.warn('ERROR: ' + e))
}
UPDATE_3
Forgot to mention that I'm creating an Android app with React Native. For testing I'm using a physical smartphone. Chrome version there is 73.0.3683.
I've replaced my fetch query with the following:
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json));
But still get the same error.
When I run it in https://jsfiddle.net/ it works. So the reason is hidden inside the code execution on a smartphone.
There must be more context to your problem; see the below snippet. This clearly works.
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json));

How to check if the response of a fetch is a json object in javascript

I'm using fetch polyfill to retrieve a JSON or text from a URL, I want to know how can I check if the response is a JSON object or is it only text
fetch(URL, options).then(response => {
// how to check if response has a body of type json?
if (response.isJson()) return response.json();
});
You could check for the content-type of the response, as shown in this MDN example:
fetch(myRequest).then(response => {
const contentType = response.headers.get("content-type");
if (contentType && contentType.indexOf("application/json") !== -1) {
return response.json().then(data => {
// The response was a JSON object
// Process your data as a JavaScript object
});
} else {
return response.text().then(text => {
// The response wasn't a JSON object
// Process your text as a String
});
}
});
If you need to be absolutely sure that the content is a valid JSON (and don't trust the headers), you could always just accept the response as text and parse it yourself:
fetch(myRequest)
.then(response => response.text()) // Parse the response as text
.then(text => {
try {
const data = JSON.parse(text); // Try to parse the response as JSON
// The response was a JSON object
// Do your JSON handling here
} catch(err) {
// The response wasn't a JSON object
// Do your text handling here
}
});
Async/await
If you're using async/await, you could write it in a more linear fashion:
async function myFetch(myRequest) {
try {
const reponse = await fetch(myRequest);
const text = await response.text(); // Parse it as text
const data = JSON.parse(text); // Try to parse it as JSON
// The response was a JSON object
// Do your JSON handling here
} catch(err) {
// The response wasn't a JSON object
// Do your text handling here
}
}
You can do this cleanly with a helper function:
const parseJson = async response => {
const text = await response.text()
try{
const json = JSON.parse(text)
return json
} catch(err) {
throw new Error("Did not receive JSON, instead received: " + text)
}
}
And then use it like this:
fetch(URL, options)
.then(parseJson)
.then(result => {
console.log("My json: ", result)
})
This will throw an error so you can catch it if you want.
Use a JSON parser like JSON.parse:
function IsJsonString(str) {
try {
var obj = JSON.parse(str);
// More strict checking
// if (obj && typeof obj === "object") {
// return true;
// }
} catch (e) {
return false;
}
return true;
}
I recently published an npm package that includes common utility functions.
one of these functions that I implemented there is just like the nis's async/await answer that you can use as bellow:
import {fetchJsonRes, combineURLs} from "onstage-js-utilities";
fetch(combineURLs(HOST, "users"))
.then(fetchJsonRes)
.then(json => {
// json data
})
.catch(err => {
// when the data is not json
})
you can find the source on Github
Fetch returns a Promise. with Promise chain, a one liner like this would work.
const res = await fetch(url, opts).then(r => r.clone().json().catch(() => r.text()));

Categories

Resources