Why does this scrape return undefined? - javascript

When I run this code I get undefined but it is clear that the ski and product_id are in the value form.
I want:
value="BTdtb4CBz3uSJ2qv"
value="adi-ss20-042"
but I get "undefined"
class TresBien {
async scrapeRaffleInfo() {
// scrape the form_key and sku values
const response = await axios(
"https://tres-bien.com/adidas-yeezy-boost-380-mist-fx9764-ss20"
);
console.log("response: ", response);
const html = await response.data;
const $ = cheerio.load(html);
const res = $('input[name="sku"]').val();
const ans = $('input[name="form_key"]').val();
console.log(res && ans);
}
}
const main = async () => {
const tb = new TresBien(
"https://tres-bien.com/adidas-yeezy-700-v3-alvah-h67799-ss20"
);
let checkoutSucc = await tb.scrapeRaffleInfo();
if (checkoutSucc) {
Logger.logEventSuccess("Raffle successfully entered");
}
};
main();

There are a few things wrong in your code:
as #Pointy mentioned, scrapeRaffleInfo() is returning undefined and you're trying to use it in checkoutSucc
Tresbien class doesn't offer any constructor, yet you're passing your url as a parameter to the constructor of that class.
You're not using any of axios library methods (like: get(), post(), put(), delete()). typically you need axios.get() but there in your code, you're just using axios()

Related

Returning data from Model.find() function in mongoose

first off I'd like to make clear that I'm new to node.js and this may sound like a silly question but, how am I supposed to return data out of model.find() function in mongoose ( eg. with a var.exports = var )?<
const data = () =>
{
MyModel.find().then(function(result){
console.log(result);
return(result);
});
}
exports.data = data
Being the query asyncronous I'm not able to retrieve these data until the function is completed (so never). Is there anyway to return these informations in a variable eg:
const retriever = require('../utils/test.js') //calling the exports file
test = retriever.data
console.log(test)
Thank you very much in advance
With promises you can achieve it as follows
const data = () => {
return MyModel.find({});
}
// using it in another function
const result = await data();
1.You can use a callback, as below
const data = (callback) =>
{
MyModel.find().then(function(result){
console.log(result);
//return(result);
callback(results);//we pass in a function which will be used to pull out
//data
});
}
exports.data = data
// THE AREA WHERE THIS CODE IS USED
const {data} = require('./to/data')
//show data
data(function (result) {
console.log( result );// data from callback
})
2. using async/await promies
const data = async () =>
{
let results = await MyModel.find();
}
exports.data = data
ON USING THIS FUNCTION
const {data} = require('./to/data')
(async function () {
let res = await data();
console.log(res);
})()

How to chain a fetch API to a function then to another function?

I keep getting syntax error "Uncaught (in promise) ReferenceError: showQuestion is not defined" Trying to find ways to fix this problem. Also I'm still new to the whole thing.
fetch(
'https://jservice.kenzie.academy/api/random-clue?valid=true'
)
.then(response => response.json())
.then(randomDataId => {
const categoryDataId = randomDataId.categoryId;
console.log(`category id is: ${categoryDataId}`);
fetch(
`https://jservice.kenzie.academy/api/clues?category=${categoryDataId}`
)
.then(response => response.json())
.then(randomCatyId => {
const rightAnswer =
randomCatyId.clues[randomData].answer;
const showTitle =
randomCatyId.clues[randomData].category.title;
const showQuestion =
randomCatyId.clues[randomData].question;
showCategory.innerText = `Category: ${showTitle}`;
h2Question.innerText = `Question: ${showQuestion}`;
console.log('question: ' + showQuestion);
console.log('answer: ' + rightAnswer);
questionFetch();
});
});
function questionFetch() {
h2Question.innerHTML = `Question: ${showQuestion}`;
}
fetch api is async in nature, and you are trying to read the data 'showQuestion' which is not yet available. please see the below code. use async-await, its much better way to play with fetch api.
const randomData = 2; // fake Data
async function GetDataFromApi(url) {
const response = await fetch(url);
return await response.json();
}
async function RunApp(params) {
const randomDataId = await GetDataFromApi('https://jservice.kenzie.academy/api/random-clue?valid=true');
const categoryDataId = randomDataId.categoryId;
console.log(`category id is: ${categoryDataId}`);
const randomCatyId = await GetDataFromApi(`https://jservice.kenzie.academy/api/clues?category=${categoryDataId}`);
const rightAnswer = randomCatyId.clues[randomData].answer;
const showTitle = randomCatyId.clues[randomData].category.title;
const showQuestion = randomCatyId.clues[randomData].question;
// showCategory.innerText = `Category: ${showTitle}`;
// h2Question.innerText = `Question: ${showQuestion}`;
console.log('question: ' + showQuestion);
console.log('answer: ' + rightAnswer);
questionFetch(showQuestion);
}
function questionFetch(showQuestion) {
//h2Question.innerHTML = `Question: ${showQuestion}`;
}
RunApp();
The function questionFetch() does not have access to the showQuestion constant. This is because this constant is defined in the fetch request. The function showQuestion does not have access to data defined inside another function.
(more on 'scope' here: https://www.w3schools.com/js/js_scope.asp)
To fix this, you should supply the constant showQuestion as an argument when calling the function questionFetch:
questionFetch(showQuestion); //we supply the constant to the function
});
});
/**
* function takes an argument, calls it x, and applies it as x.
* The name of the argument does not matter, 'x' just the label
* this function uses to hold the data supplied
* (in our case, the question string);
* */
function questionFetch(x) {
h2Question.innerHTML = `Question: ${x}`;
}
Please make sure to define and supply the [randomData] argument used in the second fetch function, as it is currently undefined.

angular 6 wait post response

var data2 = { data1Id: 0 };
postData(){
this._service1.save(data1).subscribe(res => {
this.data2.data1Id = res.Data.Id; //res.Data.Id has valid data
});
this._service2.save(data2).subscribe(res => {
console.log(this.data2.data1Id); //"this.data2.data1Id = 0" can't get value from service1
});
}
how can i get data from the first service or some function take me resolve problem run call service sequence. thank for watching !
Using async/await is perfect for your situation. It will help you to make your code more readable and make abstraction of the async part thanks to the await keyword
aync post(){
const res1 = await this._service1.save(this.data1).toPromise();
const res2 = await this._service2.save(res1).toPromise();
console.log('here is my data 2 ' + res2);
return 'what you want, can be res1 or res2 or a string';
}
How to call it ?
this.myService.post().then( (whatYouWanted) => {
console.log(whatYouWanted); // what you want, can be res1 or res2 or a string
});
this._service1.save(data1).flatMap(res => {
this.data2.data1Id = res.Data.Id; //res.Data.Id has valid data
return this._service2.save(data2);
}).subscribe(res => {
console.log(this.data2.data1Id); //"this.data2.data1Id = 0" can't get value from service1
});
You can use flatMap and return the second observable to chain them.
Documentation: http://reactivex.io/documentation/operators/flatmap.html

Unable to receive proper data from the promise function

I am trying to scrap wikipedia page to fetch list of airlines by first scrapping first page and then going to each individual page of airline to get the website url. I have divided the code in two functions. One to scrap main page and get a new url, and second function to scrap another page from the created url to get the website name from that page. I have used request-promise module for getting the html and then cheerio to parse the data.
export async function getAirlinesWebsites(req,res) {
let response = await request(options_mainpage);
console.log(`Data`);
let $ = cheerio.load(response);
console.log('Response got');
$('tr').each((i,e)=>{
let children = '';
console.log('inside function ', i);
if($(e).children('td').children('a').attr('class') !== 'new') {
children = $(e).children('td').children('a').attr('href');
let wiki_url = 'https://en.wikipedia.org' + children;
console.log(`wiki_url = ${wiki_url}`);
let airline_url = getAirlineUrl(wiki_url);
console.log(`airline_url = ${airline_url}`);
}
})
And then the getAirlineUrl() function will parse another page based on the provided url.
async function getAirlineUrl(url){
const wiki_child_options = {
url : url,
headers : headers
}
let child_response = await request(wiki_child_options);
let $ = cheerio.load(child_response);
let answer = $('.infobox.vcard').children('tbody').children('tr').children('td').children('span.url').text();
return answer;
})
However when I console log the answer variable in the parent function, I get a [object Promise] value instead of a String. How do I resolve this issue?
Async function return promise.In case of that,you need to use then to get resolved response or use await.
This should work if other part of your code is ok.
export async function getAirlinesWebsites(req, res) {
let response = await request(options_mainpage);
console.log(`Data`);
let $ = cheerio.load(response);
console.log("Response got");
$("tr").each(async (i, e) => {
let children = "";
console.log("inside function ", i);
if ($(e).children("td").children("a").attr("class") !== "new") {
children = $(e).children("td").children("a").attr("href");
let wiki_url = "https://en.wikipedia.org" + children;
console.log(`wiki_url = ${wiki_url}`);
let airline_url = await getAirlineUrl(wiki_url);
console.log(`airline_url = ${airline_url}`);
}
});
}
Since your getAirlineUrl function returns a promise, you need to await that promise. You can't have await nested inside of the .each callback because the callback is not an async function, and if it was it wouldn't work still. The best fix is the avoid using .each and just use a loop.
export async function getAirlinesWebsites(req,res) {
let response = await request(options_mainpage);
console.log(`Data`);
let $ = cheerio.load(response);
console.log('Response got');
for (const [i, e] of Array.from($('tr')).entries()) {
let children = '';
console.log('inside function ', i);
if($(e).children('td').children('a').attr('class') !== 'new') {
children = $(e).children('td').children('a').attr('href');
let wiki_url = 'https://en.wikipedia.org' + children;
console.log(`wiki_url = ${wiki_url}`);
let airline_url = await getAirlineUrl(wiki_url);
console.log(`airline_url = ${airline_url}`);
}
}
}

Getting Text From Fetch Response Object

I'm using fetch to make API calls and everything works but in this particular instance I'm running into an issue because the API simply returns a string -- not an object.
Typically, the API returns an object and I can parse the JSON object and get what I want but in this case, I'm having trouble finding the text I'm getting from the API in the response object.
Here's what the response object looks like.
I thought I'd find the text inside the body but I can't seem to find it. Where do I look?
Using the fetch JavaScript API you can try:
response.text().then(function (text) {
// do something with the text response
});
Also take a look at the docs on fetch > response > body interface methods
ES6 Syntax:
fetch("URL")
.then(response => response.text())
.then((response) => {
console.log(response)
})
.catch(err => console.log(err))
You can do this in two different ways:
The first option is to use the response.text() method, but be aware that, at Dec/2019, its global usage is only 36.71%:
async function fetchTest() {
let response = await fetch('https://httpbin.org/encoding/utf8');
let responseText = await response.text();
document.getElementById('result').innerHTML = responseText;
}
(async() => {
await fetchTest();
})();
<div id="result"></div>
The second option is to use the response.body property instead, which requires a little more work but has 73.94% of global usage:
async function fetchTest() {
let response = await fetch('https://httpbin.org/encoding/utf8');
let responseText = await getTextFromStream(response.body);
document.getElementById('result').innerHTML = responseText;
}
async function getTextFromStream(readableStream) {
let reader = readableStream.getReader();
let utf8Decoder = new TextDecoder();
let nextChunk;
let resultStr = '';
while (!(nextChunk = await reader.read()).done) {
let partialData = nextChunk.value;
resultStr += utf8Decoder.decode(partialData);
}
return resultStr;
}
(async() => {
await fetchTest();
})();
<div id="result"></div>

Categories

Resources