problem when try to fetch data from json file - javascript

I have some problems when I try to fetch the data, I didn't get response.
I write the path correctly?
I attached the part of the code and pic of my project hierarchy.
let transportation = [];
const init = () => {
fetch('/data/transportationDataCheck.json')
.then((response) => {
return response.json();
})
.then((data) => {
transportation = data;
}).then(() => {
renderList(transportation);
});
};

try this:
const data = require("../data/transportationDataCheck.json")
console.log(JSON.stringify(data));
Or you may try after changing little URL
let transportation = [];
const init = () => {
fetch('../data/transportationDataCheck.json')
.then((response) => {
return response.json();
})
.then((data) => {
transportation = data;
}).then(() => {
renderList(transportation);
});
};

You are trying to serve a static file with a fetch command, which inherently requires the file to be served by a server.
Someone had a similar issue here: Fetch request to local file not working
Depending on what type of file this is, you may not need to make a fetch. You could probably instead require the file:
var transportationDataCheck = require('./data/transportationDataCheck.json');```

Use ./ at the beginning of the path
fetch('./data/transportationDataCheck.json')
.then(response => {
return response.json()
})
.then(data => {
// Work with JSON data here
console.log(data)
})
.catch(err => {
// Do something for an error here
})

Related

Store fetch data in variable to access it later

I'm facing a probably super easy to solve problem regarding fetching.
I'd like to fetch some json datas and store it in a variable to access it later.
The problem is that I always ends up getting undefined in my variable. What's the way to do to deal with that kind of data storing ?
Here's my code.
const fetchCities = () => {
fetch('cities.json')
.then(response => response.json())
.then(data => {
return data;
});
}
let cities = fetchCities();
console.log(cities)
Already looked up for answers but couldn't find a way to do. Thanks !
You could do this very simply with async/await like this:
const fetchCities = async () => {
let cities = await fetch('cities.json');
return cities.json();
};
let cities = await fetchCities();
console.log(cities);
Sending a fetch request takes time, so the console.log works before the data arrives.
The best way to deal with fetch is using async functions and await like so:
const fetchCities = ()=>{
return fetch('cities.json');
}
async function main(){
try {
const res = await fetchCities();
const data = await res.json();
// handle the data here, this will work only after the data arrival
console.log(data);
} catch (err) {
console.log(err);
}
}
main();
Note: await can only be used in async functions, that's the main purpose of the main function.
Or if you want to use .then:
const fetchCities = ()=>{
return fetch('cities.json');
}
function main(){
fetchCities()
.then(res => res.json())
.then(data => {
// handle the data here, all you code should be here
})
.catch (err => console.log(err));
}
main();

Get http response status code after response.json()

I would like to get http status code after response.json to use it in my logic later, can I do something with it?
function apiRequest(path, options) {
fetch("api/" + path, options)
.then(response => response.json())
.then(data => {
let res = {
code: 200 //I want to put http status code here,
data: data
}
return res;
})
}
This is slightly tricky using then (as you are currently doing) because you want to get data directly from the response (which is a promise) and some more data from the parsed body (which is another promise).
So you can wrap the status and the data promise in a Promise.all and return that from the first then:
const apiRequest = () => {
const url = "//swapi.dev/api/planets/1/";
fetch(url)
.then((response) => Promise.all([response.status, response.json()]))
.then(([status, data]) => console.log({status, data}))
}
… but it would be easier to use async/await syntax and ditch the callbacks and you then only have to worry about a single function (and therefore scope) rather than multiple.
const apiRequest = async () => {
const url = "//swapi.dev/api/planets/1/";
const response = await fetch(url);
const data = await response.json();
const status = response.status;
console.log({status, data})
}
As an alternative you could consider async/await. That way you have access to response and data at the same time more easily.
async function apiRequest(path, options) {
const response = await fetch("api/" + path, options)
const data = await response.json()
let res = {
code: response.status,
data: data
}
// Do something with res
}
Try this
function apiRequest(path, options) {
fetch("api/" + path, options)
.then(response => Promise.all([Promise.resolve(response.status), response.json()]))
.then(([status, data]) => {
let res = {
code: status //I want to put http status code here,
data: data
}
return res;
})
}
you can git it in the first then before you return response.json something like this
function apiRequest(path, options) {
fetch("api/")
.then((response) => {
let status = response.status;
console.log("status", status);
return response.json();
})
.then((data) => {
console.log(data);
});
}
apiRequest();

How to fetch data from api?

I want to fetch data (particularly market cap)from api and display it inside my div. But my html diplays no data on execution. What could I be doing wrong?
<text id="result"></text>
<script>
// API for get requests
let fetchRes = fetch(
"https://api.lunarcrush.com/v2?data=assets&key=n8dyddsipg5611qg6bst9&symbol=AVAX");
// fetchRes is the promise to resolve
// it by using.then() method
fetchRes.then((res) => res.json())
.then((result) => {
console.log(result);
document.getElementById('result').innerHTML = result.config.data.0.market_cap;
})
.catch(error => {
console.log(error);
})
</script>
Two suggestions:
Why not just chain the .then() directly to the fetch()?
You seem to have a bit of confusion on how to access the data in your structure - what you're after is result.data[0].market_cap.
// API for get requests
let fetchRes = fetch("https://api.lunarcrush.com/v2?data=assets&key=n8dyddsipg5611qg6bst9&symbol=AVAX")
.then((res) => res.json())
.then((result) => {
console.log(result);
document.getElementById('result').innerHTML = result.data[0].market_cap;
})
.catch(error => {
console.log(error);
})
<text id="result"></text>
Aside: you should probably invalidate your API key that you've included here, as it's now out in public and can be used to forge requests as you to this API.
I am using jQuery Framework to do this easily.
Check the code below.
<script>
$.get(
"https://api.lunarcrush.com/v2",
{
data: "assets",
key: "n8dyddsipg5611qg6bst9",
symbol: "AVAX"
},
function (result){
data = JSON.parse(result);
}
);
</script>
You can use jQuery by adding the following code in your <head> tag.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Use result.config.data[0].market_cap; instead of result.config.data.0.market_cap;
let fetchRes = fetch(
"https://api.lunarcrush.com/v2?data=assets&key=n8dyddsipg5611qg6bst9&symbol=AVAX");
// fetchRes is the promise to resolve
// it by using.then() method
fetchRes.then((res) => res.json())
.then((result) => {
console.log(result);
document.getElementById('result').innerHTML = result.config.data[0].market_cap;
})
.catch(error => {
console.log(error);
});
You can make it cleaner and simpler:
const fetchData = async(url) => (await fetch(url)).json();
fetchData("https://api.lunarcrush.com/v2?data=assets&key=n8dyddsipg5611qg6bst9&symbol=AVAX")
.then(res => {
result.innerText = res.data[0].market_cap;
})
.catch(err => {
console.log(err);
});
<text id="result"></text>

Cypress - how to properly wait for result of an imported JS function

I am new to Cypress (and naive to JS). I would like to write a JS library as a wrapper to 3rd party APIs.
I write the API wrapper as an individual file (instead of using Cypress Custom functions) because I believe I can share the library with teams NOT using Cypress E2E tool.
The problem I am facing is "I cannot let my code to be executed sequentially in order"
From the result, I can see:
the data didn't return successfully
it looks like the "getTestPlanIdByName:20974" were executed last, but I expect it should be executed before "line 01b testPlanId:{}"
I need to help to know the correct way to handle the flow sequentially in Cypress/Javascript, thanks.
API Library(api-util.js)
let axios = require('axios');
const proxy = "http://10.8.8.8:8080/";
const apiPatToken = 'OmdrvbvvvvvvvvWZqa2E='
let proxyAgentHttps = require('https-proxy-agent');
let proxyAgentHttp = require('http-proxy-agent');
let agentHttps = new proxyAgentHttps(proxy);
let agentHttp = new proxyAgentHttp(proxy);
let config = {
baseURL: 'https://dev.3rdparty.com/mycompany/myaccount/_apis',
url: 'DUMMY_INJECTED_LATER',
httpsAgent: agentHttps,
httpAgent: agentHttp,
proxy:false,
headers: {
'Authorization': `Basic ${apiPatToken}`
}
}
export async function getTestPlanIdByName(testplan_name){
config.url = '/test/plans?api-version=5.0'
let found = ''
axios.request(config).then( resp => {
found = resp.data.value.find(function(item, index, array){
return item.name === testplan_name
})
})
.then(() => {
console.log("getTestPlanIdByName:"+found.id)
return found.id
})
.catch(err => console.log(err))
}
My Cypress code
import * as UTIL from 'api-util.js'
describe('CI-', () => {
let testPlanId = 'none'
it('01 Get TestPlanID', () => {
//use cy.log() get a Promise for flow control
cy.log()
.then(() => {
new Cypress.Promise((resolve, reject) => {
console.log("01a testPlanId:"+JSON.stringify(testPlanId))
testPlanId = UTIL.getTestPlanIdByName("TESTPLAN-Regression")
console.log("01b testPlanId:"+JSON.stringify(testPlanId))
})
})
.then(() => {
console.log("01c testPlanId:"+JSON.stringify(testPlanId))
})
});
it('02 Get TestSuitesList', () => {
console.log("02 testPlanId:"+testPlanId)
// UTIL.getTestSuitesIdList(testPlanId)
});
});
Thank you all. Cypress flow isn't 100% compatible with standard JS Promise (Wait for an own function (which returns a promise) before tests are executed). After relentless testings, I decided to use a Cypress Custom Command wrapper to wrap my in-house JS library. Though adding an extra layer may seem a little cumbersome. But I am satisfied with the result. Share my code here in case anyone might need it. :)
Cypress Code
before('Prepare TestPlanId', () => {
cy.getTestPlanIdByName(testPlanName)
.then((result) => {
testPlanId = result
console.log("#01_SDET_testplan:Prepare TestPlanId# "+testPlanId)
})
});
Cypress Custom Command
Cypress.Commands.add('getTestPlanIdByName', (wk_testplan_name) => {
return new Cypress.Promise((resolve, reject) => {
TESTPLAN_API.getTestPlanIdByName(wk_testplan_name)
.then(function (data) {
resolve(data);
})
});
})
In-house JS library
export async function getTestPlanIdByName(wk_testplan_name){
return new Promise((resolve, reject) => {
config.method = 'get'
config.url = '/test/plans?api-version=5.0'
let found = ''
axios.request(config).then( resp => {
found = resp.data.value.find(function(item, index, array){
return item.name === wk_testplan_name
})
})
.then(() => {
resolve(found.id)
})
.catch(err => console.log(err))
})
}

Can I use crawled from Node.js in javaScript?

I'm new to javaScript and trying to crawl a website with node.js. I could check the data in console log, but want to use the data in another javaScript file. How can I fetch the data?
The problem is I've never used node.js. I do javaScript so I know how to write the code, but I don't know how the back-end or server works.
I've tried to open it in my local host but the node method (e.g., require()) didn't work. I found out it's because node doesn't work in browser.(See? very new to js)
Should I use bundler or something?
The steps I thought were,
somehow send the data as json
somehow fetch the json data and render
Here is the crawling code file.
const axios = require("axios");
const cheerio = require("cheerio");
const log = console.log;
const getHtml = async () => {
try {
return await axios.get(URL);
} catch (error) {
console.error(error);
}
};
getHtml()
.then(html => {
let ulList = [];
const $ = cheerio.load(html.data);
const $bodyList = $("div.info-timetable ul").children("li");
$bodyList.each(function(i, elem) {
ulList[i] = {
screen: $(this).find('a').attr('data-screenname'),
time: $(this).find('a').attr('data-playstarttime')
};
});
const data = ulList.filter(n => n.time);
return data;
})
.then(res => log(res));
Could you please explain what steps should I take?
Also, it would be great if I can get understood WHY the steps are needed.
Thanks alot!
you can try writing your data to a JSON file and proceed, that's one way, then you can use the data as an object in any js file
const appendFile = (file, contents) =>
new Promise((resolve, reject) => {
fs.appendFile(
file,
contents,
'utf8',
err => (err ? reject(err) : resolve()),
);
});
getHtml()
.then(html => {
let ulList = [];
const $ = cheerio.load(html.data);
const $bodyList = $("div.info-timetable ul").children("li");
$bodyList.each(function(i, elem) {
ulList[i] = {
screen: $(this).find('a').attr('data-screenname'),
time: $(this).find('a').attr('data-playstarttime')
};
});
const data = ulList.filter(n => n.time);
return data;
})
.then(res => {
return appendFile('./data.json',res.toString())
}))
.then(done => {log('updated data json')});

Categories