How to iterate json object after async fetching json in jQuery? - javascript

I have an issue with iterating json object in jQuery after fetching asynchronly.
With async function 'listFiles' I managed to succesfully get the desired filelist of directory (dir), at least console.log shows json with content.
But when I try to call $.each on fetched filelist json object, $.each simply doesn't work.
The console.log inside $.each function should output something.
async function listFiles(dir){
var json_data = await fetch('action.php', {
method: 'POST',
mode: "same-origin",
credentials: "same-origin",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({dir:dir})
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
return data
})
.catch((error) => {
console.error('Error:', error);
});
return json_data;
}
var json = listFiles('images');
$(() => {
$.each(json, function(index,val){ //this function doesn't work, dunno why :(
console.log("index: "+index+"; value: "+val);
})
console.log(json); //this shows fetched json object's content
});

You code should look something like below, you were using async-await and also using callbacks, and also you were printing data when it was not available.
async function listFiles(dir) {
try {
const response = await fetch('action.php', {
method: 'POST',
mode: "same-origin",
credentials: "same-origin",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ dir: dir })
})
const json_data = await response.json();
console.log('Success:', json_data);
return json_data;
}
catch (error) {
console.error('Error:', error);
}
}
async function printJsonData() {
var json = await listFiles('images');
$.each(json, function (index, val) { // now it should work :)
console.log("index: " + index + "; value: " + val);
})
console.log(json); //this shows fetched json object's content
}
printJsonData();

Related

How to return translated text JavaScript google Translate API

I wrote the following code to translate from Arabic to English, I want the function to accept English as source and return the translated text,
can some one help me on this?
translateArtoEn(source) {
let url = `https://translation.googleapis.com/language/translate/v2?key=${API_KEY}`;
url += '&q=' + encodeURI(source);
url += `&source=ar`;
url += `&target=en`;
console.log(url)
fetch(url, {
method: 'GET',
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then(res => res.json())
.then((response) => {
return response.data.translations[0]["translatedText"]
})
.catch(error => {
console.log("There was an error with the translation request: ", error);
});
}
The code you provided will not return any value since I assume the function is synchronous.
With this, you may use callback function to return the desired result after the parent function has already returned.
Please see below code for your reference:
const fetch = require('node-fetch');
function main(){
var source = '<your_desired_text_to_translate>';
translateArtoEn(source,myDisplayer);
}
function translateArtoEn(source,callback){
var API_KEY = '<your_API_key>';
let url = `https://translation.googleapis.com/language/translate/v2?key=${API_KEY}`;
url += '&q=' + encodeURI(source);
url += `&source=ar`;
url += `&target=en`;
fetch(url, {
method: 'GET',
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
})
.then(res => res.json())
.then((response) => {
callback(response.data.translations[0].translatedText)
})
.catch(error => {
console.log("There was an error with the translation request: ", error);
});
}
function myDisplayer(result) {
// handle the result here
console.log("Translated text: ",result);
}
if (require.main === module) {
main();
}
In this code, callback is used to pass the returned value (after the execution of the parent function is finished) to another function that will handle the result.

Unable to display a response from Axios

I am new to using Axios and struggling to display anything from a response function. I'm mainly interested to see see at least the response status. The only output I can see is when there is a 4xx code returned, but nothing when the call is successful.
Below is my code, any help would be appreciated:
setServiceGroupPromise(){
//Read data from ./data/sourcingRules.txt
let filePath = './data/sourcingRules.txt';
var fileData = fs.readFileSync(filePath, 'utf8');
console.log(fileData);
let postURL = `${siteConfig}`;
const config = {
method: 'post',
url: postURL,
params: {
'apiKey': process.env.SHIPPING_SERVICE_API_KEY
},
headers: {
'content-type': 'application/xml',
},
data: fileData
};
console.log(`Post request going to: ${postURL}`);
axios(config)
.then(function (response) {
console.log(response.data);
console.log(response.status);
})
.catch(function (error) {
console.log('The following error occurred : ' + error.message);
});
}
If you are not seeing anything from the console.log(response.data), try logging something like console.log({response}), or console.log('show me something', response.data)

Javascript in VueJs: how to return data object from async fetch instead of Promise

I have this action in store
actions: {
testLogin(context, credentials) {
const loginService = new FetchClient();
let d = loginService.post('login', credentials);
console.log(d);
},
and this function in another class imported to store
async post(endpoint, params) {
await fetch(this.url + endpoint, {
'method': 'POST',
headers: this.headers,
body: JSON.stringify(params),
})
.then(response => {
return response.json();
})
.then( (data) => {
this.returnData = data.data;
})
.catch(error => {
console.log(error);
});
return this.returnData;
}
And I get PromiseĀ {<pending>} which I can extract data from inside the fetch class but can't access data if I'm in the store because it's a Promise not an object. How can I solve this?
Put the return statement inside the second then block:
async post(endpoint, params) {
await fetch(this.url + endpoint, {
'method': 'POST',
headers: this.headers,
body: JSON.stringify(params),
})
.then(response => {
return response.json();
})
.then( (data) => {
this.returnData = data.data;
return this.returnData;
})
.catch(error => {
console.log(error);
});
}
I would even recommend you use the following code for better legibility:
async post(endpoint, params) {
const response = await fetch(this.url + endpoint, {
'method': 'POST',
headers: this.headers,
body: JSON.stringify(params),
})
if (!response.ok) {
const message = `An error has occured: ${response.status}`;
throw new Error(message);
}
const resp_data = await response.json()
return resp_data.data
}
Then call your method like so:
post(endpoint, params)
.then(data => {// do something with data})
.catch(error => {
error.message; // 'An error has occurred: 404'
});
refer to this async/await guide
Can you try:
async testLogin(context, credentials) {
const loginService = new FetchClient();
let d = await loginService.post('login', credentials);
console.log(d);
}
As #Ayudh mentioned, try the following code:
async post(endpoint, params) {
try{
let response = await fetch(this.url + endpoint, {
'method': 'POST',
headers: this.headers,
body: JSON.stringify(params),
});
let data = await response.json();
this.returnData = data.data;
}catch(e){
console.log(e);
}
return this.returnData;
}

axios transformResponse returning undefined

With the following I get the expected response.data value:
axios({
method,
url
}).then(response => { console.log(response) })
However, when I add the transformResponse property as follows I get a response.data value of undefined:
axios({
method,
url,
transformResponse: [(data) => {
return data
}]
}).then(response => { console.log(response) })
Can someone please tell me what I'm missing here! Thanks
I suggest you to use interceptors since they are more clean
Interceptors work as a middlware on your requests
remove transformResponse and add this
axios.interceptors.response.use(function (response) {
return response.data;
});
axios({
method,
url,
}).then(response => { console.log(response) })
You can check the below sample to safe parse. transformResponse get data as raw staring so u can parse it.
const instance = axios.create({
baseURL: baseURL,
transformResponse: [
(data) => {
let resp;
try {
resp = JSON.parse(data);
} catch (error) {
throw Error(
`[requestClient] Error parsingJSON data - ${JSON.stringify(
error
)}`
);
}
if (resp.status === "success") {
return resp.data;
} else {
throw Error(`Request failed with reason - ${data}`);
}
},
],
});
Else you can use an interceptor to simplify it.
//const axios = require("axios");
const jsonInterceptor = [
(response) => response.data,
(error) => Promise.reject(error),
];
function jsonClient() {
const client = axios.create();
client.interceptors.response.use(...jsonInterceptor);
return client;
}
// Page 1
const jhttp = jsonClient();
jhttp
.get("https://jsonplaceholder.typicode.com/todos/1")
.then((data) => console.log(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
For anyone wondering here is the response:
axios.get(url, {
headers: {
'Content-Type': 'application/json'
},
transformResponse: axios.defaults.transformResponse.concat((data) => {
console.log(data) // this should now be JSON
})
})
from https://github.com/axios/axios/issues/430#issuecomment-243481806

Axios and response data set split to multiple arrays

I'm trying to get data from an API using axios command like
function fetchData(apiURL){
let data = [];
let options = {
method: "GET",
url: apiURL,
headers: {
"Access-Control-Allow-Origin": "*"
},
credentials: "include"
};
axios(options)
.then(response => {
data = response.data;
console.log(data);
})
.catch(function (error) {
console.log("System error : " + error);
});
return data;
}
but that will produce sets of arrays which will store arrays of JSONs from response.data in count of 100 per array set.
I haven't had problem using fetch() to retrieve all data. How I can get similar response of one large array of JSON objects instead of a split?
PS.
I have triggered that function in the
componentDidMount() {
const apiURL = process.env.REACT_APP_API;
let tableData = fetchData(apiURL);
console.log("DATA " + JSON.stringify(tableData));
this.setState({tblData : tableData});
}
Axios requests are asynchronous and return promises, so you need to adjust your example a bit so that your function returns a promise.
/**
* #return {Promise<T>}
*/
function fetchData(apiURL){
const options = {
method: "GET",
url: apiURL,
headers: {
"Access-Control-Allow-Origin": "*"
},
credentials: "include"
};
return axios(options)
.then(response => {
return response.data;
})
}
Now, when you consume this API do so asynchronously.
function somethingThatUpdatesThatUI() {
fetchData("/api/foo/bar")
.then((data) => {
//perform updates to UI or state here
})
.catch((err) => {
//alert the users that an error has happened here
})
}
You can update the componentDidMount function:
componentDidMount() {
const apiURL = process.env.REACT_APP_API;
fetchData(apiURL).then(data => {
console.log(data ${JSON.stringify(tableData)})
this.setState({tblData : data});
})
}

Categories

Resources