Pass result .js to another .js - javascript

I want to pass result from var url (index.js) to game.js, so that it follows the process that I need. Is that possible? Any help will be appreciated, thank you very much.
I put the complete index.js code so that you understand what you want to achieve.
I've tried to do it in many ways, but none successfully, I don't know what else to try.
index.js
//SELECT CATEGORY
//CATEGORY => 8, 9, 10, 11, ..., 32
const obj = {
url: 'https://opentdb.com/api.php?amount=20',
category: '',
difficulty: ''
}
let newUrl = Object.values(obj).join('');
function selectCat() {
var c = document.getElementById('cat').value;
console.log(c);
obj.category = c;
newUrl = Object.values(obj).join('');
}
//SELECT DIFFICULTY
//DIFFICULTY => any, easy, medium, hard
function selectDiff() {
var d = document.getElementById('diff').value;
console.log(d);
obj.difficulty = d;
newUrl = Object.values(obj).join('');
}
/*NEST VALUE TO CATEGORY AND DIFFICULTY
NEXT TO THE URL TO GET THE NEWURL*/
//CLICK EVENT BUTTON
var btnFetch = document.getElementById('fetch');
/*var url =*/ btnFetch.addEventListener('click', function(e) {
console.log(newUrl);});
game.js
fetch(
url
)
.then(res => {
return res.json();
})
.then(loadedQuestions => {
console.log(loadedQuestions.results);
questions = loadedQuestions.results.map(loadedQuestion => {
const formattedQuestion = {
question: loadedQuestion.question
};
const answerChoices = [...loadedQuestion.incorrect_answers];
formattedQuestion.answer = Math.floor(Math.random() * 3) + 1;
answerChoices.splice(
formattedQuestion.answer - 1,
0,
loadedQuestion.correct_answer
);
answerChoices.forEach((choice, index) => {
formattedQuestion["choice" + (index + 1)] = choice;
});
return formattedQuestion;
});
startGame();
})
.catch(err => {
console.error(err);
});

Related

How to modify the code to only use one of the folders with the similar first word in their name using javascript?

The following code is used to generate NFTs by combining layers which are located inside folders.
What if I wanted to use the entire collection of folders provided in props.folderNames but also force the program that if among the folders provided there were more than one folder with the similar first word (for example "Face Old" and "Face New") it only use one of these folders for the generation process randomly and not both of the at once.
For example the the first artwork is generated by combining the layers inside the "Face Old" and "Hats New" folder and the second artwork is generated by combining the layers inside the "Face new" and "Hats futuristic" folder etc.
const constructLayerToDna = (_dna = "", _layers = []) => {
let mappedDnaToLayers = _layers.map((layer, index) => {
let selectedElement = layer.elements.find(
(e) => e.id == cleanDna(_dna.split("-")[index])
);
return {
name: layer.name,
selectedElement: selectedElement,
};
});
return mappedDnaToLayers;
};
const startCreating = async () => {
props.setProgress(0);
let editionCount = 1;
let failedCount = 0;
while (editionCount <= props.config.supply) {
let newDna = createDna(props.folderNames);
if (isDnaUnique(dnaList, newDna)) {
let results = constructLayerToDna(newDna, props.folderNames);
let loadedElements = [];
results.forEach((layer) => {
loadedElements.push(loadLayerImg(layer));
});
await Promise.all(loadedElements).then((renderObjectArray) => {
ctx.clearRect(0, 0, props.config.width, props.config.height);
renderObjectArray.forEach((renderObject, index) => {
drawElement(renderObject, index);
});
saveImage(editionCount);
addMetadata(newDna, editionCount);
saveMetaDataSingleFile(editionCount);
console.log(`Created edition: ${editionCount}`);
});
dnaList.add(filterDNAOptions(newDna));
editionCount++;
props.setProgress(editionCount - 1);
} else {
console.log("DNA exists!");
failedCount++;
if (failedCount >= 1000) {
console.log(
`You need more layers or elements to grow your edition to ${props.config.supply} artworks!`
);
process.exit();
}
}
}
writeMetaData(JSON.stringify(metadataList, null, 2));
};
I tried adding the following code:
const folderGroups = props.folderNames.reduce((groupedFolders, folder) => {
const folderName = folder.toString().split(" ")[0];
groupedFolders[folderName] = groupedFolders[folderName] || [];
groupedFolders[folderName].push(folder);
return groupedFolders;
}, {});
const selectedFolders = Object.values(folderGroups).map((folderGroup) => {
const randomIndex = Math.floor(Math.random() * folderGroup.length);
return folderGroup[randomIndex];
});
and also changed the startCreating function to this:
const startCreating = async () => {
props.setProgress(0);
let editionCount = 1;
let failedCount = 0;
while (editionCount <= props.config.supply) {
let newDna = createDna(selectedFolders);
if (isDnaUnique(dnaList, newDna)) {
let results = constructLayerToDna(newDna, selectedFolders);
// rest of the code
However, this didn't work and resulted in the program to only use one of the folders provided to it out of the entire collection of folders.

Node.js How to retrieve data from http.get response

I am doing some practice in node.js. In this exercise I been asked to find a country name through a GET Http Request to an endpoint passing a page integer as a parameter.
Where the important response structs are these {page, total_pages, data}.
page is the current page,
total_pages is the last page,
data is an array of 10 country object.
In getCountryName func I am able to retrieve the right answer only if the answer is on the 1st page, the 1 iteration of the loop. So, why the loop only happens once?
Aditional, I wanted to retrieve the total_pages to replace the hardcode '25' value but I do not figure it out how to return it along with the search.
Any hint you wanna give me? The whole problem is in getCountryCode func.
'use strict';
const { Console } = require('console');
const https = require('https');
function makeRequest(page){
return new Promise(resolve => {
let obj='';
https.get('https://jsonmock.hackerrank.com/api/countries?page='+page, res => {
let data ='';
res.on('data',function(chunk){
data+=chunk;
});
res.on('end',function(){
obj=JSON.parse(data);
resolve(obj);
});
});
});
}
async function getCountryName(code) {
var res = '';
var pages = 25;
var i = 1;
while(i <= pages && res == ''){
console.log(i);
res = makeRequest(i)
.then(data => {
let f = ''
let p = data['total_pages'];
let search = data['data'].find(o => o.alpha3Code === code);
f = search != null ? search['name'] : f;
return f;
});
i++;
}
return res;
}
async function main() {
const name = await getCountryName('ARG');
console.log(`${name}\n`);
}
main();
Without modifying your code too much, this is how you do it:
'use strict';
const { Console } = require('console');
const https = require('https');
function makeRequest(page){
return new Promise(resolve => {
let obj='';
https.get('https://jsonmock.hackerrank.com/api/countries?page='+page, res => {
let data ='';
res.on('data',function(chunk){
data+=chunk;
});
res.on('end',function(){
obj=JSON.parse(data);
resolve(obj);
});
});
});
}
async function getCountryName(code) {
const pages = 25;
var i = 1;
let f = null
while(i <= pages && f === null){
console.log(i);
const data = await makeRequest(i) // put in try/catch
const p = data['total_pages'];
const search = data['data'].find(o => o.alpha3Code === code);
f = search !== null ? search['name'] : null;
i++;
}
return res;
}
async function main() {
const name = await getCountryName('ARG');
console.log(`${name}\n`);
}
main();

Incrementing number and saving it with put method

There is a page with two images where you can vote to one of the pictures.
After the voting two new images is loading randomly and so on. The votes should be
incremented and saved to the server, but here comes the problem that I can not put the incremented
number, because I get an array: [{"votes":2},null]
I'd like to increment, save, and load the two new images with one onClick event.
Here it is what I tried to do:
handelVote(id) {
this.setState(
prevState => ({ //I get an array
voteNr: prevState.castles.map(c =>
c.id === id ? { votes: c.votes + 1 } : console.log(this.state.voteNr)
)
})
this.getCastles(),
axios
.put("............." + id, {
vote: this.state.voteNr
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
})
);
}
here I'm getting the data from the server and load only two pictures and the belonging two votes:
componentDidMount() {
if (this.state.castles.length === 0) this.getCastles();
}
async getCastles() {
let castles = [];
let voteNr = [];
let i = [];
for (i = 0; i < 1; i++) {
const f = z(4); //random nr from Choise.js
const uniqueSet = new Set(f); //to avoid duplicates
const b = [...uniqueSet];
if (b.length < 2) {
b.shift();
b.push(1, 2); //in case of duplicates load the first two images
}
let res = await axios.get(".....");
let { data } = res;
let castle = data;
this.setState({ castles: castle });
for (i = 0; i < 2; i++) {
//load only two
var t;
t = b[i];
let name = castle[t].name;
let id = castle[t]._id;
let image = castle[t].image;
let votes = castle[t].vote;
castles.push({ image, name, id, votes });
voteNr.push({votes});
}
}
this.setState(prevState => ({
loading: false,
castles: [...castles]
}));
}
and after this comes the already qouted onClick event what makes the problems.

How to trigger firebase http function in node.js?

I am trying to trigger an another function in Firebase Cloud function with javascript. But i always getting an error of Can't set headers after they are sent. Please take a look at my code below: ................. ................. ............ ................ ................. ............... ....................... .................. ..............
exports.productIndexShuffleOne = functions.https.onRequest(async (req, res) => {
const interval = req.query.interval;
console.log("interval: "+interval);
const productRef = admin.firestore().collection("Products");
const adminRef = admin.firestore().collection("Admin").doc("totalProd").get();
const dateRef = admin.firestore().collection("Admin").doc("totalProd").collection("indexShuffle").doc("productShuffle").get();
return dateRef.then(documentSnapshot => {
const setDate = documentSnapshot.get('date').seconds;
var nextDay = setDate;
console.log("Date: "+nextDay);
const x = setInterval(function() {
clearInterval(x);
return Promise.all([adminRef]).then(result => {
const totalNum = result[0].data().totalNumber;
console.log("totalNum: "+totalNum);
var numberList = [];
var index = 1;
while(index <= totalNum){
numberList.push(index);
index++;
}
var cidx, ridx, tmp;
cidx = numberList.length;
while (cidx !== 0) {
ridx = Math.floor(Math.random() * cidx);
cidx--;
tmp = numberList[cidx];
numberList[cidx] = numberList[ridx];
numberList[ridx] = tmp;
}
console.log(numberList);
var counter = 0;
return productRef.get().then(snapshot => {
snapshot.forEach(doc => {
const prodID = doc.get('productID');
const index = doc.get('index');
var newIndex = numberList[counter];
counter++;
console.log("oldIndex: "+index);
console.log("newIndex: "+newIndex);
productRef.doc(prodID).update({
index: newIndex
}, {merge: true});
});
return res.redirect('https://us-central1-myfunction-123456.cloudfunctions.net/productIndexShuffleTwo?interval='+interval);
})
.catch(err => {
console.log('Error getting documents', err);
});
});
}, interval);
return res.status(203).send(interval);
}).catch(function(err) {
console.error(err);
});
});
This is because you've sent multiple responses while the rule is that you only allowed sending one response. Please try to look at your code and optimize it in such a way that it contains only one response.
I can see you have multiple responses as below:
1 -> return res.redirect('https://us-central1-myfunction-123456.cloudfunctions.net/productIndexShuffleTwo?interval='+interval);
2 -> return res.status(203).send(interval);
I believe that you can have res.redirect and then res.status.send called one after another. When you writing endpoints there rule of a thumb: always send response and only do that once. Refactor your code so there no way you can make those two calls, but only one of them.

find cities and country name from string

I have cities and countires list in a json file. For a given string, I need to check the city name and country name is present or not. If present I have to capitalize the word. what is the best way to acheive this in node JS
Please consider json from this link.
https://raw.githubusercontent.com/russ666/all-countries-and-cities-json/master/countries.json
my input is "united states to play davis cup in bratislava"
output should be "United States to play davis cup in Bratislava"
Hint: First letter of city and country name should be capital.
I am expecting code something like this
var myString="united states to play davis cup in bratislava";
var data=myjson;
var i=0;
myString=myString.split("");
for(i=0;i<myString.length;i++){
var output="";
//help this line
var check=myString[i].match(data)
if(check){
output+=myString[i].charAt(0).toUpperCase() + myString[i].slice(1);
}
else{
output+=myString[i]}
}
It all starts from function start() at the bottom. For displaying purpose i've used a small dataset but you can require the data from the json file by using const data = require('data.json'). I've tested for large dataset also, works like a charm. Hope it helps.
const data = {
"United States":[
"Washington","Bratislava","Hard","Going"],
"Afghanistan": [
"Herat",
"Kabul",
"Kandahar",
"Molah",
"Rana",
"Shar",
"Sharif",
"Wazir Akbar Khan"
]};
Array.prototype.myJoin = function(start,end){
if(!start) start = 0;
if(!end) end = this.length - 1;
end++;
return this.slice(start,end);
};
const getCityData = async (country) => {
return country;
}
const changeFormat = async () => {
try {
let countries = Object.keys(data).map( (country, index) => {
return country;
})
let citiesData = [];
await countries.map( (country, index) => {
citiesData = citiesData.concat(data[country]);
})
return countries.concat(citiesData);
} catch (err) {
return err;
}
}
const checkSentence = (text, text_original, number, modified_data) => {
return new Promise((resolve, reject)=>{
try {
if( !text || !text.length ){
throw new Error('empty text');
}
// console.log('started ' + number);
// console.log('number ' + number +' started')
let upperCase = [];
const number_const = number;
let temp1 = new Array(text.length);
temp1.fill(2);
temp1.map( (v, i) => {
// let temp = text;
let temp = [...text_original, ...[]];
// console.log('i' + i);
// console.log('number' + number);
if(i + number <= text.length ) {
// console.log('inside 1st if');
temp = temp.slice(i, i + number)
// console.log(text + ' 1');
temp = temp.join(' ')
// console.log(text + ' 2');
temp = temp.toLowerCase();
// console.log(text + ' 3');
if(modified_data.indexOf(temp) != -1){
upperCase.push({ start: i, end: i + number - 1 })
}
}
})
let toBeChanged = [];
if(upperCase.length){
upperCase.map( (v, i) => {
// console.log(v);
let arr = range( v.start, v.end )
toBeChanged = toBeChanged.concat(arr);
})
}
// console.log('ended number' + number);
// console.log(toBeChanged);
return resolve(toBeChanged);
} catch (err) {
return reject(err);
// console.error(err);
// return false;
}
})
}
const range = (start, end) => {
// console.log(start);
// console.log(end);
return Array(end - start + 1).fill().map((_, idx) => start + idx)
}
const start = async() => {
try {
excludeWords.map( (word, index) => {
excludeWords[index] = excludeWords[index].toLowerCase();
});
let modified_data_1 = await changeFormat();
let maximum = 1;
modified_data = modified_data_1.map( (v, i) => {
if(v.split(' ').length > maximum){
maximum = v.split(' ').length
}
if(excludeWords.indexOf(v.toLowerCase()) == -1) {
return v.toLowerCase();
}
});
text = text.split(' ');
if(maximum > text.length){
maximum = text.length;
}
// console.log(maximum);
let temp = new Array(maximum);
temp.fill(2);
let answer = await temp.map( (v, i) => {
let tempArray = [...text, ...[]];
let tempArray1 = [...text, ...[]];
return checkSentence(tempArray, tempArray1, (maximum - i), modified_data);
})
return Promise.all(answer).then( (results) => {
let merged = [].concat.apply([], results);
// console.log('merged');
merged = new Set(merged);
merged = [...merged];
// console.log(merged);
merged.map((v, i) => {
if(v == undefined || v == null){
return;
}
let temp1 = text[v].split('');
temp1[0] = temp1[0].toUpperCase();
text[v] = temp1.join('');
})
// console.log(text.join(' '));
return text.join(' ');
}).catch((err)=>{
console.log(err);
})
} catch (err) {
// console.error('here ERROR');
console.error(err);
return false;
}
}
let excludeWords = ['Hard', 'Going'];
let text = 'united states to davis cup hard wazir Akbar Khan in bratislava';
( async () => {
let answer = await start();
console.log(answer);
})();
Hi I have done in simple way it is also working. My problem is in the string the word "davis" also present as a city in json. How to not capitalize that word. For ex: "Hard", "Going" these words also have city name. but these words not be considered as city in my program.
Case 1:
Input: taiwan hit hard by sars outbreak.
Output should be: Taiwan hit hard by sars outbreak.
My output: Taiwan hit Hard by sars outbreak.
Please install capitalize npm and use data.json folder in your root folder to execute below code
var myData=require("./data");
var countriesArray=Object.keys(myData.data);
var citiesArray=Object.values(myData.data);
var capitalize=require('capitalize');
var citiesFlatten = [].concat.apply([], citiesArray);
var countryCities=countriesArray.concat(citiesFlatten);
var str = 'russia ponders space tourism deal';
var pattern = new RegExp("\\b("+countryCities.join("|")+")\\b","ig");
var matchArray=str.match(pattern);
if(!!matchArray){
matchArray.forEach(function(item) {
str=str.replace(item,capitalize.words(item));
});
console.log( str.replace(/^\w/, c => c.toUpperCase()));
}

Categories