ReferenceError: variable is not define - Node.js - javascript

oddsData is undefined when i want to run the code below.
getOdds = async(data) => {
var receivedData = "";
send({"Command":"GetMatchMarkets","Params":data});
var message = JSON.stringify({"Command":"GetMatchMarkets","Params":data});
var length = Buffer.byteLength(message),
buffer = new Buffer(4 + Buffer.byteLength(message));
buffer.writeUInt32LE(length, 0);
buffer.write(message, 4);
client.write(buffer);
var bytesToReceive = length;
var oddsData = "";
client.on('data', async(buf) => {
function calc(){
var offset = 0;
if (bytesToReceive === 0) {
if(buf.length < 4){ return; }
bytesToReceive = buf.readUInt32LE(0);
offset = 4;
}
var currentCommandBytes = Math.min(bytesToReceive, buf.length - offset);
receivedData += buf.slice(offset, offset + currentCommandBytes);
bytesToReceive -= currentCommandBytes;
if (bytesToReceive === 0) {
bytesToReceive = 0;
if (receivedData != ""){
oddsData += receivedData;
}
receivedData = "";
}
if (currentCommandBytes < buf.length - offset) {
calc(buf.slice(currentCommandBytes+offset))
}
}
await calc();
});
console.log(oddsData);
}
return ReferenceError: oddsData is not defined.
oddsData is undefined when i want to run the code below.

Assuming you used oddsData in in your ...OTHER CODES..., maybe the error is due to those nesting of functions,
Declare functions as variables and then pass it to your code.
function test(){
var calc = function (){
...OTHER CODES....
receivedData = "";
return oddsdata
}
var asFun = async (buf) => {
await calc();
}
var oddsData = "";
client.on('data', asFun);
console.log(oddsData);
}

[updated to match changes in question's code]
Stripping out all the code that doesn't affect oddsData leaves the following structure:
const getOdds = async () => {
var oddsData = '';
client.on('data', async () => {
function calc () {
oddsData += 'something';
}
await calc();
});
console.log(oddsData);
};
I see no indication that oddsData should be undefined.
A little test program to explore what's happening:
const getOdds = async() => {
result.innerHTML += 'enter getOdds async()\n';
var oddsData = "";
client.addEventListener('data', async() => {
result.innerHTML += `client.on data async() oddsData: '${oddsData}'\n`;
function calc() {
oddsData += "calc!";
result.innerHTML += `calc() oddsData: '${oddsData}'\n`;
}
await calc();
});
result.innerHTML += `getOdds async() oddsData: '${oddsData}'\n`;
};
window.onload = () => {
result.innerHTML = 'window.onload calling getOdds()\n';
getOdds();
}
<p id="client">This is client.
<button onclick="emitData()">Emit 'data' to client</button>
</p>
<p>Results:</p>
<pre id="result"></pre>
<script>
const client = document.getElementById('client');
const result = document.getElementById('result');
function emitData() {
let event = new Event('data');
client.dispatchEvent(event);
}
</script>

Related

Firebase Cloud Function isnt work in Prod. Getting error

I am getting the following error when going to the URL.
Error: could not handle the request
I can not seem to figure out why. What did I do wrong?
Here is my index.js file.
const functions = require('firebase-functions');
var request = require('request');
const admin = require('firebase-admin');
admin.initializeApp();
exports.addMessage = functions.https.onRequest(async (req, res) => {
const itemDescription = req.query.itemDescription;
const pageNumber = req.query.pageNumber;
const categoryId = req.query.categoryId;
const sortBy = req.query.sortBy;
const narrowSearch = req.query.narrowSearch;
const typeOfListing = req.query.typeOfListing;
const sellerExclusions = req.query.sellerExclusions;
const tagsExclusions = req.query.tagsExclusions;
const country = req.query.country;
const minPrice = req.query.minPrice;
const maxPrice = req.query.maxPrice;
const entriesPerPage = req.query.entriesPerPage;
const buyingFormat = req.query.buyingFormat;
let operationName = "";
let entriesPerPage2 = "";
let sortOrder = "";
let currentPage = "";
if (pageNumber !== null) {
currentPage = pageNumber;
} else {
currentPage = 1;
}
if (typeOfListing === 'active') {
operationName = "findItemsAdvanced";
entriesPerPage2 = 50;
} else {
operationName = "findCompletedItems";
if (buyingFormat === "Auction") {
entriesPerPage2 = 50;
} else {
entriesPerPage2 = 25;
}
}
let apicall = "https://URL?";
if (typeOfListing === "active") {
if (sortBy !== null) {
apicall += "&sortOrder=";
apicall += sortBy;
sortOrder = sortBy;
} else {
apicall += "&sortOrder=";
apicall += "BestMatch";
sortOrder = "BestMatch";
}
} else {
if (sortBy !== null) {
apicall += "&sortOrder=";
apicall += sortBy;
sortOrder = sortBy;
} else {
apicall += "&sortOrder=";
apicall += "EndTimeSoonest";
sortOrder = "EndTimeSoonest";
}
}
if (categoryId !== null) {
apicall += "&categoryId=";
apicall += categoryId;
}
apicall += "&paginationInput.pageNumber=";
apicall += currentPage;
apicall += "&keywords=";
apicall += itemDescription;
apicall += "&paginationInput.entriesPerPage=" + entriesPerPage2;
apicall += "&itemFilter(0).name=SoldItemsOnly&itemFilter(0).value(0)=true";
request(apicall, function (error, response, body) {
if (!error && response.statusCode === 200) {
//here put what you want to do with the request
let paginationOutput = JSON.parse(body).findCompletedItemsResponse[0].paginationOutput;
let pageNumber = null;
let totalPages = null;
let totalEntries = null;
let totalInPage = null;
for (i = 0; i < paginationOutput.length; i++) {
pageNumber = paginationOutput[i].pageNumber[0];
totalPages = paginationOutput[i].totalPages[0];
totalEntries = paginationOutput[i].totalEntries[0];
totalInPage = paginationOutput[i].entriesPerPage[0];
}
let items = JSON.parse(body).findCompletedItemsResponse[0].searchResult[0].item;
let itemId = null;
let title = null;
let categoryId = null;
let categoryName = null;
let galleryURL = null;
let link = null;
let dateEnded = null;
let watchCount = null;
let bestOfferEnabled = null;
let listingType = null;
let soldForOriginal = null;
let timeLeft = null;
let dateLeft = null;
let bidCount = null;
let shipping = null;
//TODO
let soldForBestOffer = null;
var itemArray = {
result: []
};
for (i = 0; i < items.length; i++) {
itemId = items[i].itemId[0];
title = items[i].title[0];
galleryURL = items[i].galleryURL[0];
link = items[i].viewItemURL[0];
category = items[i].primaryCategory;
for (j = 0; j < category.length; j++) {
categoryName = category[j].categoryName[0];
categoryId = category[j].categoryId[0];
}
listingInfo = items[i].listingInfo;
for (k = 0; k < listingInfo.length; k++) {
watchCount = listingInfo[k].watchCount === undefined ? "0" : listingInfo[k].watchCount[0];
bestOfferEnabled = listingInfo[k].bestOfferEnabled[0];
listingType = listingInfo[k].listingType[0];
dateLeft = listingInfo[k].endTime[0];
}
sellingStatus = items[i].sellingStatus;
for (jj = 0; jj < sellingStatus.length; jj++) {
soldForOriginal = sellingStatus[jj].convertedCurrentPrice[0].__value__;
bidCount = sellingStatus[jj].bidCount === undefined ? "0" : sellingStatus[jj].bidCount[0];
timeLeft = sellingStatus[jj].timeLeft === undefined ? "-" : sellingStatus[jj].timeLeft[0];
}
shippingInfo = items[i].shippingInfo;
for (ii = 0; ii < shippingInfo.length; ii++) {
shipping = shippingInfo[ii].shippingServiceCost === undefined ? "0.0" : shippingInfo[ii].shippingServiceCost[0];
shippingType = shippingInfo[ii].shippingType[0];
if (shipping === "0.0") {
shipping = "0.00"
}
if (shippingType === 'Calculated') {
shipping = "TBD";
} else {
if (shipping === '0.00') {
shipping = "FREE";
}
}
}
itemArray.result.push({
"itemId": itemId,
"title": title,
"galleryURL": galleryURL,
"link": link,
"categoryName": categoryName,
"categoryId": categoryId,
"bidCount": bidCount,
"dateEnded": dateLeft,
"watchCount": watchCount,
"bestOfferEnabled": bestOfferEnabled,
"listingType": listingType,
"timeLeft": timeLeft,
"soldForOriginal": soldForOriginal
});
}
res.json({
ack: "success",
message: "results found",
currentPage: pageNumber,
totalPages: totalPages,
totalEntries: totalEntries,
totalInPage: totalInPage,
results: itemArray.result,
searchResult: JSON.parse(body).findCompletedItemsResponse[0].searchResult[0].item
});
} else {
res.json({
error: "didnt work"
});
}
})
});
In Cloud Functions you need to manage asynchronous method calls via Promises. request supports callback interfaces natively but does not return a promise.
You should use another library, like axios, along the following lines:
exports.addMessage = functions.https.onRequest(async (req, res) => {
try {
// ...
let apicall = "https://URL?";
// ...
apicall += "&itemFilter(0).name=SoldItemsOnly&itemFilter(0).value(0)=true";
const response = await axios.get(apicall);
// handle success
// ...
res.json({..});
} catch (error) {
res.status(500).send({ 'error': error });
}
});
Note that you probably need to be on the "Blaze" pricing plan.
As a matter of fact, the free "Spark" plan "allows outbound network requests only to Google-owned services". See https://firebase.google.com/pricing/ (hover your mouse on the question mark situated after the "Cloud Functions" title)
Also note that request is deprecated.

Intended of Load JQuery once function in other js file executed completely

I am fetching some data from the database and based on retrieved data HTML is being rendered on the browser. Once the HTML is being rendered then I want to apply JQuery on them. following is my code
fetch_items.js File
async function itemsWithAllDetails() {
let responseData = await retrieveItems();
let itemsWithSizes = await getSizes(responseData);
let itemsWithImages = await getImages(itemsWithSizes);
let itemsWithColors = await getColors(itemsWithImages);
let filtered_items_sales = filterItems(itemsWithColors, 'sales_section');
renderItems(filtered_items_sales, "sales_section");
let filtered_items_boys = filterItems(itemsWithColors, 'BOYS');
renderItems(filtered_items_boys, "boys_section");
let filtered_items_girls = filterItems(itemsWithColors, 'GIRLS');
renderItems(filtered_items_girls, "girls_section");
let filtered_items_bboys = filterItems(itemsWithColors, 'BABY BOYS');
renderItems(filtered_items_bboys, "baby_boy_section");
let filtered_items_bgirls = filterItems(itemsWithColors, 'BABY GIRLS');
renderItems(filtered_items_bgirls, "baby_girl_section");
let filtered_items_men = filterItems(itemsWithColors, 'MEN');
renderItems(filtered_items_men, "men_section");
let filtered_items_women = filterItems(itemsWithColors, 'WOMEN');
renderItems(filtered_items_women, "women_section");
}
itemsWithAllDetails();
JQuery File
$(document).ready(function () {
$("button.increament").click(function () {
let x = $(this).siblings("input").val();
if (x == "") {
x = 0;
}
x = parseInt(x);
if (x >= 5) {
alert("You can not order more than 5");
}
else {
$(this).siblings("input").val(x + 1);
}
});
$("button.decreament").click(function () {
let x = $(this).siblings("input").val()
if (x >= 1) {
$(this).siblings("input").val(parseInt(x) - parseInt(1));
}
});
// Increment Decrement Buttons End Here
});
Why events are not working? What I am doing wrong/missing here?
i did it by excluding events from $(document).ready();
Then include them in another function and called it from itemsWithAllDetails function at the end.

javascript multiple function callback syntax

I can't wrap my head around callback syntax, can you please help me re-write my code so that it executes in this order:
MenuBuilder.load()
MenuBuilder.draw()
Translator.load()
(in my case it executes in this order MenuBuilder.load(), Translator.load(), MenuBuilder.draw() so it doesn't do what I want)
onload.js
import MenuBuilder from "./menu-builder.js";
import Translator from "./translator.js";
var menuBuilder = new MenuBuilder();
var translator = new Translator();
menuBuilder.load();
translator.load();
menu-builder.js
"use strict"
class MenuBuilder {
constructor() {
this._nav = document.getElementsByTagName("nav")[0];
this._url = window.location.href;
}
load() {
console.log("MenuBuilder.load() start");
fetch(`/json/menu.json`)
.then((res) => res.json())
.then((jsonMenu) => {
this.draw(jsonMenu);
})
/*.catch(() => {
console.error(`Could not load ${this._lang}.json.`);
});*/
console.log("MenuBuilder.load() end");
}
draw(jsonMenu) {
console.log("MenuBuilder.draw(jsonMenu) start");
var htmlMenu = `<div id="siteTitleDiv"><p id="siteTitle" data-i18n="general.title"></p><p id="siteTitleShadow" data-i18n="general.title-shadow"></p><p id="siteSubtitle"data-i18n="general.subtitle"></p></div><ul>`;
for(var i = 0; i < jsonMenu.length; i++) {
var menuItem = jsonMenu[i];
var regexp = /http:\/\/cypher-f\.com\/(([a-z\-]*\/)?([a-z\-]*\/))?/g;
var fullPage = "something format_abc";
var match = regexp.exec(this._url);
var level_1 = match[1];
var level_2 = match[3];
var parent = match[2];
var full_suffix = match[0];
if ((parent == null) || (menuItem.parent === parent)) {
var material_icon = menuItem["material-icon"];
var href = menuItem["href"];
var i18n = menuItem["data-i18n"];
htmlMenu += `<li><i class="material-icons">${material_icon}</i></li>`;
}
}
htmlMenu += `</ul>`;
this._nav.innerHTML = htmlMenu;
console.log("MenuBuilder: nav.innerHTML");
console.log(this._nav.innerHTML);
console.log("MenuBuilder: document.elements");
console.log(document.querySelectorAll("[data-i18n]"));
console.log("MenuBuilder.draw(jsonMenu) end");
}
}
export default MenuBuilder;
translator.js
"use strict"
class Translator {
constructor() {
this._lang = this.getLanguage();
this._elements = document.querySelectorAll("[data-i18n]");
}
getLanguage() {
var lang = navigator.languages ? navigator.languages[0] : navigator.language;
return lang.substr(0, 2);
}
load(lang = null) {
console.log("Translator.load() start");
console.log("this._elements");
console.log(this._elements);
if (lang) {
this._lang = lang;
}
else {
var re = new RegExp("lang=([^;]+)");
var value = re.exec(document.cookie);
var cookieLang = (value != null) ? unescape(value[1]) : null;
if (cookieLang) {
this._lang = cookieLang;
}
}
fetch(`/i18n/${this._lang}.json`)
.then((res) => res.json())
.then((translation) => {
this.translate(translation);
})
.then(this.toggleLangTag())
.then(document.cookie = `lang=${this._lang};path=/`)
/*.catch(() => {
console.error(`Could not load ${this._lang}.json.`);
});*/
console.log("Translator.load() end");
}
translate(translation) {
console.log("Translator.load(translation) start");
this._elements.forEach((element) => {
var keys = element.dataset.i18n.split(".");
var text = keys.reduce((obj, i) => obj[i], translation);
if (text) {
element.innerHTML = text;
}
else {
element.innerHTML = `key ${keys} not found for ${this._lang}!`
}
});
console.log("Translator.load(translation) end");
}
toggleLangTag() {
if (document.documentElement.lang !== this._lang) {
document.documentElement.lang = this._lang;
}
}
switchLanguage(translator) {
var availableLang = ["en", "fr"];
var currentLangIndex = availableLang.indexOf(translator._lang);
var nextLang = availableLang[(currentLangIndex + 1)%availableLang.length];
translator.load(nextLang);
}
}
export default Translator;
I'm sorry I know this is kind of a newbie question but I haven't programmed in three years.
You're working with Promises here, so you want to stick with that paradigm. Return the promise that is returned from the fetch call, then "chain" off of that promise to call the translator.
load() {
console.log("MenuBuilder.load() start");
// The return here gives control of the promise to the caller...
return fetch(`/json/menu.json`)
.then((res) => res.json())
.then((jsonMenu) => {
this.draw(jsonMenu);
})
/*.catch(() => {
console.error(`Could not load ${this._lang}.json.`);
});*/
console.log("MenuBuilder.load() end");
}
So back in onload.js you can use the promise returned from menuBuilder.load() to call translator.load() after menuBuilder.load() is done.
import MenuBuilder from "./menu-builder.js";
import Translator from "./translator.js";
var menuBuilder = new MenuBuilder();
var translator = new Translator();
menuBuilder.load().then(() => translator.load());

How do I make this function reusable?

How do I make this function reusable by passing 2 parameters, totalPrice and currentPrice.
This is the code (it works perfectly, but I want this to be in a separate function so I could use it later on):
$(".btn-quantity").on('click', function () {
var $button = $(this);
var oldValue = $button.parent().find("input").val();
var totalPrice = document.querySelector(".table-price-total"); // I need this querySelector to be the function's first argument
var currentPrice = document.querySelector(".table-price-current"); // And this the second argument
var newVal = parseFloat(oldValue);
if ($button.hasClass("btn-quantity--plus")) {
newVal++;
} else {
if (newVal - 1 > 0) {
newVal--;
}
}
let result = newVal * parseFloat(currentPrice.innerHTML);
totalPrice.innerHTML = result.toFixed(2);
$button.parent().find("input").val(newVal);
})
The error I currently get is: Uncaugh TypeError: $btn.parent is not a function
This is what I've tried:
let $btn = document.querySelector(".btn-quantity");
let btnFunc = (currentPrice, totalPrice) => {
$btn = document.querySelector(".btn-quantity");
let oldValue = $btn.parent().find("input").val();
let cPrice = document.querySelector(currentPrice);
let tPrice = document.querySelector(totalPrice);
let newVal = parseFloat(oldValue);
if ($btn.hasClass("btn-quantity--plus")) {
newVal++;
} else {
if (newVal - 1 > 0) {
newVal--;
}
}
let result = newVal * parseFloat(cPrice.innerHTML);
tPrice.innerHTML = result.toFixed(2);
$btn.parent().find("input").val(newVal);
}
$btn.addEventListener('click', (event) => {
event.preventDefault();
btnFunc(".table-price-current", ".table-price-total");
})
Generally you'd do that by using a function that makes other functions:
function makePriceCalculator(totalPrice, currentPrice) {
return function() {
var $button = $(this);
var oldValue = $button.parent().find("input").val();
var newVal = parseFloat(oldValue);
if ($button.hasClass("btn-quantity--plus")) {
newVal++;
} else {
if (newVal - 1 > 0) {
newVal--;
}
}
let result = newVal * parseFloat(currentPrice.innerHTML);
totalPrice.innerHTML = result.toFixed(2);
$button.parent().find("input").val(newVal);
};
}
Then your posted example would be written as
$(".btn-quantity").on('click', makePriceCalculator(document.querySelector(".table-price-total"), document.querySelector(".table-price-current"));

Undefined Result in HTML

I created this function which should give me back 105; 6.5 and 110; 4.5 instead of this I receive undefined: undefinedundefined: undefined
Can anyone tell my what I have to do that I get the right result? I read something with asynchron, but I'm not really sure what I have to chance?!
Here is my function (in Meteor isClient)...
var d = 0;
var finalReturn = "";
while(distinctPlayer[d]) {
var total = 0;
Spieltag.find({SpielerID: distinctPlayer[d]}).map(function (doc) {
total += doc.Note;
});
var finalName = 0;
Spieltag.find({SpielerID: distinctPlayer[d]}).map(function (doc) {
finalName = doc.SpielerID;
});
finalReturn += finalName[d] +": "+ total[d];
d++;
}
return finalReturn;
And in the HTML, it looks like this
<p>
<pre>{{otherHelperFunction}}</pre>
</p>
try to use fetch() after find() and before map()
var d = 0;
var finalReturn = "";
while(distinctPlayer[d]) {
var total = 0;
Spieltag.find({SpielerID: distinctPlayer[d]}).fetch().map(function (doc) {
total += doc.Note;
});
var finalName = 0;
Spieltag.find({SpielerID: distinctPlayer[d]}).fetch().map(function (doc) {
finalName = doc.SpielerID;
});
finalReturn += finalName[d] +": "+ total[d];
d++;
}
return finalReturn;

Categories

Resources