I understand that this question has been asked before but none of the previous answers have helped me.
This is my function:
function execute() {
console.log('here')
const q = document.getElementById('myinput').value
return gapi.client.youtube.search.list({
"part": "snippet",
"order": "viewCount",
"q": q,
"type": "video",
"videoDefinition": "high",
"maxResults": 10
})
.then(function(response) {
console.log("Response", response);
const z = response.result.items
console.log("x", z)
return(z.map(vid => {
console.log("vid", vid)
const date = document.createElement('div')
const title = document.createElement('h2')
const video = document.createElement('iFrame')
date.textContent = vid.snippet.publishedAt
title.textContent = vid.snippet.title
const x = document.getElementById('results')
console.log(date)
x.append(date)
x.append(title)
x.append(video)
const w = document.getElementById('date')
const v = document.getElementById('view')
function sorting(){
const items = vid.childNodes;
const itemsArr = [];
for (var i in items) {
if(items[i].nodeType == 1){
itemsArr.push(items[i])
}
}
itemsArr.sort(function(a,b){
return a.innerHTML === b.innerHTML
? 0
: (a.innerHTML > b.innerHTML ? 1 : -1);
});
for (i = 0; i < itemsArr.length; ++i){
w.appendChild(itemsArr[i])
}
}
return(x)
}))
},
function(err) { console.error("Execute error", err); });
}
I want to trigger that sorting function on my onclick: <option onclick="execute().sorting()"id = "date">Date</option>
If you know how I can call it or even if you know a better way of sorting videos by date and view count, please leave a comment or answer. Any help is appreciated.
OH! I should add, this has to be done in pure vanilla javascript.
Edit
You asked for the HTML:
<button onclick="execute()">Search</button>
<h3>Sort:</h3>
<select>
<option onclick="execute.b()"id="view" value="viewCount">View Count</option>
<option onclick="execute().sorting()"id = "date">Date</option>
</select>
You can create a constructor function with a nested function sorting scoped to this object when initiated, and then initiate it in js i.e.:
function Execute() {
this.search = function(){
console.log('here')
const q = document.getElementById('myinput').value
return gapi.client.youtube.search.list({
"part": "snippet",
"order": "viewCount",
"q": q,
"type": "video",
"videoDefinition": "high",
"maxResults": 10
})
.then(function(response) {
console.log("Response", response);
const z = response.result.items
console.log("x", z)
return (z.map(vid => {
console.log("vid", vid)
const date = document.createElement('div')
const title = document.createElement('h2')
const video = document.createElement('iFrame')
date.textContent = vid.snippet.publishedAt
title.textContent = vid.snippet.title
const x = document.getElementById('results')
console.log(date)
x.append(date)
x.append(title)
x.append(video)
const w = document.getElementById('date')
const v = document.getElementById('view')
this.sorting();
return (x)
}))
},
function(err) {
console.error("Execute error", err);
});
};
this.sorting = function() {
const items = vid.childNodes;
const itemsArr = [];
for (var i in items) {
if (items[i].nodeType == 1) {
itemsArr.push(items[i])
}
}
itemsArr.sort(function(a, b) {
return a.innerHTML === b.innerHTML ?
0 :
(a.innerHTML > b.innerHTML ? 1 : -1);
});
for (i = 0; i < itemsArr.length; ++i) {
w.appendChild(itemsArr[i])
}
};
}
Then create an instance when the whole page loads:
var executeInstance;
window.onload = function(event){
executeInstance = new Execute();
};
And in the HTML then call the instance (not sure what function b is, not present in initial example):
<button onclick="executeInstance.search()">Search</button>
<h3>Sort:</h3>
<select>
<option onclick="executeInstance.b()"id="view" value="viewCount">View Count</option>
<option onclick="executeInstance.sorting()"id = "date">Date</option>
</select>
More on Object Constructor:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
Related
I am trying to build money conversion calculator but the result showing NaN. Can anyone help me with it.
Tried a lot but could not solve it.
Here's the js code
const dropList = document.querySelectorAll("form select"),
fromCurrency = document.querySelector(".from select"),
toCurrency = document.querySelector(".to select"),
getButton = document.querySelector("form button");
for (let i = 0; i < dropList.length; i++) {
for (let currency_code in country_list) {
let selected =
i == 0
? currency_code == "USD"
? "selected"
: ""
: currency_code == "NPR"
? "selected"
: "";
let optionTag = `<option value="${currency_code}" ${selected}>${currency_code}</option>`;
dropList[i].insertAdjacentHTML("beforeend", optionTag);
}
dropList[i].addEventListener("change", (e) => {
loadFlag(e.target);
});
}
function loadFlag(element) {
for (let code in country_list) {
if (code == element.value) {
let imgTag = element.parentElement.querySelector("img");
imgTag.src = `https://flagcdn.com/48x36/${country_list[
code
].toLowerCase()}.png`;
}
}
}
window.addEventListener("load", () => {
getExchangeRate();
});
getButton.addEventListener("click", (e) => {
e.preventDefault();
getExchangeRate();
});
const exchangeIcon = document.querySelector("form .icon");
exchangeIcon.addEventListener("click", () => {
let tempCode = fromCurrency.value;
fromCurrency.value = toCurrency.value;
toCurrency.value = tempCode;
loadFlag(fromCurrency);
loadFlag(toCurrency);
getExchangeRate();
});
function getExchangeRate() {
const amount = document.querySelector("form input");
const exchangeRateTxt = document.querySelector("form .exchange-rate");
let amountVal = amount.value;
amountVal = parseFloat(amountVal);
if (amountVal == "" || amountVal == "0") {
amount.value = "1";
amountVal = 1;
}
exchangeRateTxt.innerText = "Getting exchange rate...";
let url = `https://api.fastforex.io/convert?from=${fromCurrency.value}&to=${toCurrency.value}&amount=${amountVal}&api_key=xxx-xxx-xxx`; // api key on p
fetch(url)
.then((response) => response.json())
.then((result) => {
let exchangeRate = result.rate;
let totalExRate = (amountVal * exchangeRate).toFixed(2);
exchangeRateTxt.innerText = `${amountVal} ${fromCurrency.value} = ${totalExRate} ${toCurrency.value}`;
})
.catch(() => {
exchangeRateTxt.innerText = "Something went wrong";
});
}
Here's the response data
{
"base": "USD",
"amount": 1,
"result": {
"AED": 3.67,
"rate": 3.67189
},
"ms": 5
}
This part of your code seems to be the issue:
let amountVal = amount.value;
amountVal = parseFloat(amountVal);
if (amountVal == "" || amountVal == "0") {
amount.value = "1";
amountVal = 1;
}
where parseFloat() evaluates as NaN right away when the value is empty.
Replace that with:
let amountVal = parseFloat(amount.value ?? "1");
amount.value = amount.value ?? "1"
The ?? operator is useful to set a default value on nullish or undefined.
The result in your .then((result) => method is the response data, and there is no rate value but has result.rate
var result = {
"base": "USD",
"amount": 1,
"result": {
"AED": 3.67,
"rate": 3.67189
},
"ms": 5
};
console.log( result.rate ); // undefined
console.log( result.result.rate ); // 3.67189
// assuming that amountVal is 1
let amountVal = 1;
let exchangeRate = result.result.rate;
let totalExRate = (amountVal * exchangeRate).toFixed(2);
console.log( totalExRate ); // 3.67
We need to get the field from the NetSuite Record page, i.e. workOrder.
I've created a single JS file that defines the pageInit function and where I'm getting the xyz field value.
I'd like to have the NetSuite xyz field locally in the console so I can use it in my Java-script code to make it dynamic.
But here, I am unable to get an exact solution for it.
How can we get the value of a netsuite (work-order page) form field using lambda and Node.js?
I don't see anything in your question that requires node so far. If you really need to use node you should look at the RESTlet/SuiteTalk options mentioned in the comments.
If you are wanting to run a script in the console the code below shows how to do that.
I keep a folder of these for various admin tasks. Just open a console and run when needed. The code below is fairly complex for one of these scripts (though not the most complex by far). It is used while editing a role. It presents a list of roles that have been set up with minimal permissions for a particular job function. The roles that are selected have their permissions applied to the currently being edited role.
N/currentRecord is the API that loads the current record's data.
require(['N/search', 'N/currentRecord', 'N/xml'], function(search, currentRecord, xml) {
const roleList = search.create({
type:'role',
filters:[
['custrecord_kotn_is_role_capabilities', 'is', 'T'], 'AND',
['isinactive', 'is', 'F']
],
columns:['name']
}).run().getRange({start:0, end:1000}).map(ref=>{
return {
id:ref.id,
name:ref.getValue({name:'name'})
};
}).map(r=>(`<option value=${r.id}>${r.name}</option>`)).join('\n');
console.log(roleList);
const body = document.querySelector('body');
const form=`
<div id="kotn-choose-roles" style="position:fixed;width:320px;left:50%;transform:translateX(-50%);top:30vh;background-color:white;border:1px solid #ccc;padding:10px;">
<form onSubmit="return false;">
<table><tr>
<td>Roles</td>
<td><select multiple id="kotn-roles-chosen">${roleList}</select>
</td>
</tr>
<tr><td colspan="2" align="center"><button id="kotn-apply-roles" type="button">Apply</button><button id="kotn-cancel-roles" type="button">Cancel</button>
</table>
</form>
</div>
`;
const frag = document.createElement('div');
frag.setAttribute('id', 'kotn-role-chooser');
frag.innerHTML = form;
body.appendChild(frag);
jQuery('#kotn-apply-roles').bind('click', function(){
const roleIds = jQuery('#kotn-roles-chosen').val();
console.log(roleIds);
applyRoles(roleIds);
alert('done');
frag.parentNode.removeChild(frag);
});
jQuery('#kotn-cancel-roles').bind('click', function(){
frag.parentNode.removeChild(frag);
});
function applyRoles(permSources){
const roleRec = currentRecord.get();
const machineNames = [
{
name:'custrecordmach',
permRef:'custrecord',
permLevelField:'permittedlevel',
restricted:'restriction'
},
{
name:'tranmach',
permRef: 'permkey1',
permLevelField:'permlevel1'
},
{
name:'listsmach',
permRef:'permkey3',
permLevelField:'permlevel3'
},
{
name:'setupmach',
permRef:'permkey4',
permLevelField:'permlevel4'
}
];
function doPerms(){
if(!permSources.length) return;
processPerm(permSources.shift()).then(doPerms);
}
function processPerm(id){
return fetchWithRetry(`/app/setup/role.nl?id=${id}&xml=T`,{
credentials: 'same-origin'
}).
then(resp =>{
console.log(id, resp.status);
return resp.text();
}).
then(data=>{
const roleDoc = xml.Parser.fromString({
text: data
});
console.log('role: ',selectValue(roleDoc, '/nsResponse/record/name'));
machineNames.forEach(m=>{
console.log('process machine', `//machine[#name="${m.name}"]/line`);
const docLines = xml.XPath.select({
node: roleDoc,
xpath: `//machine[#name="${m.name}"]/line`
});
console.log('machine lines', m.name, docLines.length);
const lines = docLines.map(line=>{
const perm = {
perm: selectValue(line, m.permRef),
level:parseInt(selectValue(line, m.permLevelField),10),
restricted:null
};
if(m.restricted){
perm.restricted = parseInt(selectValue(line, m.restricted), 10);
}
return perm;
});
console.log('lines for', m.name, lines);
const findPermIndex = perm =>{
for(var i = 0; i< lines.length; i++){
if(lines[i].perm == perm) return i;
}
return -1;
};
iter(roleRec, m.name, (idx, getV) =>{
const perm = getV(m.permRef);
const applyingIndex = findPermIndex(perm);
if(applyingIndex == -1) return;
const applyingPerm = lines.splice(applyingIndex, 1)[0];
console.log('have current perm', JSON.stringify(applyingPerm));
const permVal = getV(m.permLevelField);
const applyingLevel = (permVal >= applyingPerm.level) ? permVal : applyingPerm.level;
let applyingRestriction = null;
if(m.restricted){
let restrictionVal = parseInt(getV(m.restricted), 10) || null;
applyingRestriction = (!restrictionVal) ? null : applyingPerm.restricted;
if(restrictionVal && applyingRestriction){
if(applyingRestriction <restrictionVal){
applyingRestriction = restrictionVal;
}
}
}
setTimeout(()=>{
roleRec.selectLine({sublistId:m.name, line:idx});
roleRec.setCurrentSublistValue({sublistId:m.name, fieldId:m.permLevelField, value:applyingLevel, forceSyncSourcing:true});
if(applyingRestriction){
roleRec.setCurrentSublistValue({sublistId:m.name, fieldId:m.restricted, value:applyingRestriction, forceSyncSourcing:true});
}
roleRec.commitLine({sublistId:m.name});
}, idx *20);
});
lines.forEach((line, idx)=>{
console.log('adding ', m.name, JSON.stringify(line));
setTimeout(()=>{
roleRec.selectNewLine({sublistId:m.name});
roleRec.setCurrentSublistValue({sublistId:m.name, fieldId:m.permRef, value:line.perm, forceSyncSourcing:true});
roleRec.setCurrentSublistValue({sublistId:m.name, fieldId:m.permLevelField, value:line.level, forceSyncSourcing:true});
if(m.restricted){
roleRec.setCurrentSublistValue({sublistId:m.name, fieldId:m.restricted, value:line.restricted, forceSyncSourcing:true });
}
roleRec.commitLine({sublistId:m.name, ignoreRecalc:true});
}, idx*100);
});
});
return id;
}).catch(e=>{
console.error(e.message);
return null;
});
}
doPerms();
}
//load role
//for each machine
// transfer perms
// check current level - use highest
function selectValue(node, path) {
const targets = xml.XPath.select({
node: node,
xpath: path
});
if (!targets || !targets.length) return null;
return targets[0].firstChild.nodeValue;
}
// function selectAttribute(node, path, attr) {
// const targets = xml.XPath.select({
// node: node,
// xpath: path
// });
// if (!targets || !targets.length) return null;
// return targets[0].getAttribute(attr);
// }
function iter(rec, listName, cb){
var lim = rec.getLineCount({sublistId:listName});
var i = 0;
var getV = function (fld){
return rec.getSublistValue({sublistId:listName, fieldId:fld, line:i});
};
for(; i< lim; i++){
cb(i, getV);
}
}
async function fetchWithRetry(url, opts, tries = 3) {
const errs = [];
const waiter = async (pause) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(null);
}, pause);
});
};
for (let i = 0; i < tries; i++) {
// log for illustration
if(i != 0) console.error(`trying GET '${url}' [${i + 1} of ${tries}]`);
try {
const resp = await fetch(url, opts);
return resp;
} catch (err) {
errs.push(err);
await waiter(800 * i + 1);
}
}
throw errs;
}
});
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());
I've done some searching around the web and nothing seems to solve my problem. I have the following jQuery code:
function youtube_data_parser(data) {
//---> parse video data - start
var qsToJson = function(qs) {
var res = {};
var pars = qs.split('&');
var kv, k, v;
for (i in pars) {
kv = pars[i].split('=');
k = kv[0];
v = kv[1];
res[k] = decodeURIComponent(v);
}
return res;
}
//---> parse video data - end
var get_video_info = qsToJson(data);
if (get_video_info.status == 'fail') {
return {
status: "error",
code: "invalid_url",
msg: "check your url or video id"
};
} else {
// remapping urls into an array of objects
//--->parse > url_encoded_fmt_stream_map > start
//will get the video urls
var tmp = get_video_info["url_encoded_fmt_stream_map"];
if (tmp) {
tmp = tmp.split(',');
for (i in tmp) {
tmp[i] = qsToJson(tmp[i]);
}
get_video_info["url_encoded_fmt_stream_map"] = tmp;
}
//--->parse > url_encoded_fmt_stream_map > end
//--->parse > player_response > start
var tmp1 = get_video_info["player_response"];
if (tmp1) {
get_video_info["player_response"] = JSON.parse(tmp1);
}
//--->parse > player_response > end
//--->parse > keywords > start
var keywords = get_video_info["keywords"];
if (keywords) {
key_words = keywords.replace(/\+/g, ' ').split(',');
for (i in key_words) {
keywords[i] = qsToJson(key_words[i]);
}
get_video_info["keywords"] = {
all: keywords.replace(/\+/g, ' '),
arr: key_words
};
}
//--->parse > keywords > end
//return data
return {
status: 'success',
raw_data: qsToJson(data),
video_info: get_video_info
};
}
}
function getVideoInfo() {
var get_video_url = $('#ytdlUrl').val();
var get_video_id = getUrlVars(get_video_url)['v'];
var video_arr_final = [];
var ajax_url = "video_info.php?id=" + get_video_id;
$.get(ajax_url, function(d1) {
var data = youtube_data_parser(d1);
var video_data = data.video_info;
var player_info = data.video_info.player_response;
var video_title = player_info.videoDetails.title.replace(/\+/g, ' ');
var fmt_list = video_data.fmt_list.split(',');
var video_thumbnail_url = video_data.thumbnail_url;
var video_arr = video_data.url_encoded_fmt_stream_map;
//create video file array
$.each(video_arr, function(i1, v1) {
var valueToPush = {};
valueToPush.video_url = v1.url;
valueToPush.video_thumbnail_url = video_thumbnail_url;
valueToPush.video_title = video_title;
$.each(fmt_list, function(i2, v2) {
var fmt = v2.split('/');
var fmt_id = fmt[0];
var fmt_quality = fmt[1];
if (fmt_id == v1.itag) {
valueToPush.fmt_id = fmt_id;
valueToPush.fmt_quality = fmt_quality;
}
});
video_arr_final.push(valueToPush);
});
});
return video_arr_final;
}
function getUrlVars(url) {
var vars = {};
var parts = url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) {
vars[key] = value;
});
return vars;
}
function fillInOptions(ytOptions) {
//console.log(ytOptions);
//alert(ytOptions[0]);
var ytFill = ytOptions;
console.log(ytFill);
//ytFill.forEach(function(i,v) {
var ytdlOptions = $('#ytdlOptions');
ytFill.forEach(function(i,v) {
console.log(i);
ytdlOptions.append(new Option(v.fmt_quality, v.fmt_id));
});
return true;
}
function showYTDLLoader() {
$('#ytdlInput').fadeOut(1000, function() {
$('#ytdlLoader').fadeIn(500);
});
var options = getVideoInfo();
//console.log(options);
if (fillInOptions(options) == true) {
//do rest
}
}
function showYTDLOptions() {
return true;
}
function startDownload() {
showYTDLLoader();
}
function hideYTDLLoader() {
$('#ytdlLoader').fadeOut(500);
}
function animateCSS(element, animationName, callback) {
const node = $(element);
node.addClass(animationName);
function handleAnimationEnd() {
node.removeClass(animationName);
node.animationend = null;
if (typeof callback === 'function') callback();
}
node.animationend = handleAnimationEnd();
}
When my button is clicked, I call showYTDLLoader() which gets an array of objects from the YouTube API that looks like this:
[
{
"video_url": "https://r7---sn-uxanug5-cox6.googlevideo.com/videoplayback?expire=1572496003&ei=Iw66Xa24H8PL3LUPiN25mAs&ip=2001%3A8003%3A749b%3Aa01%3A5cd8%3Ac610%3A6402%3Ad0fe&id=o-ADsVnoOoBQ6-SWzYZU7gHES06s7xQptJG6hn9WcakITY&itag=22&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-uxanug5-cox6%2Csn-ntqe6n7r&ms=au%2Crdu&mv=m&mvi=6&pl=39&initcwndbps=1655000&mime=video%2Fmp4&ratebypass=yes&dur=917.768&lmt=1572418007364260&mt=1572474311&fvip=4&fexp=23842630&c=WEB&txp=5535432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRgIhAIp-4gyUTLoXFetbY0ha_YnR7DJqsp_MNjjIxqDdfPZJAiEA_WPd21jgX9broBcigf8rcSEVoJb2_NX7t3XZQqytsSM%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHylml4wRAIgacvP3zjEq-rVEZFrX7a_hC6TR-Zab7Ii-Fbaupjs_PcCIHdZht4l4ioYL3ERz7WNiSbnOnhm5iYxEECaQXPP2hUp",
"video_title": "Arnold Schwarzenegger on Son-in-law Chris Pratt, Pranking Sylvester Stallone & Terminator’s Return",
"fmt_id": "22",
"fmt_quality": "1280x720"
},
{
"video_url": "https://r7---sn-uxanug5-cox6.googlevideo.com/videoplayback?expire=1572496003&ei=Iw66Xa24H8PL3LUPiN25mAs&ip=2001%3A8003%3A749b%3Aa01%3A5cd8%3Ac610%3A6402%3Ad0fe&id=o-ADsVnoOoBQ6-SWzYZU7gHES06s7xQptJG6hn9WcakITY&itag=18&source=youtube&requiressl=yes&mm=31%2C29&mn=sn-uxanug5-cox6%2Csn-ntqe6n7r&ms=au%2Crdu&mv=m&mvi=6&pl=39&initcwndbps=1655000&mime=video%2Fmp4&gir=yes&clen=44248820&ratebypass=yes&dur=917.768&lmt=1572416976690256&mt=1572474311&fvip=4&fexp=23842630&c=WEB&txp=5531432&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cgir%2Cclen%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRQIhANTZJlBHFWQWCnfK11yvLiPUV26c6NzvqIMKjDwmsByMAiBUSy0ZJMo4GdHSiRU4xBDDLxLtzwKZAqAKCiB-1aViDQ%3D%3D&lsparams=mm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHylml4wRAIgacvP3zjEq-rVEZFrX7a_hC6TR-Zab7Ii-Fbaupjs_PcCIHdZht4l4ioYL3ERz7WNiSbnOnhm5iYxEECaQXPP2hUp",
"video_title": "Arnold Schwarzenegger on Son-in-law Chris Pratt, Pranking Sylvester Stallone & Terminator’s Return",
"fmt_id": "18",
"fmt_quality": "640x360"
}
]
But when I try and loop through each entry with fillInOptions(), my loop is never completed because the length is apparently zero. However, when I dump the array using console.log() it tells me the length is 2, and displays the above. I need to be able to add each option to my dropdown.
Thankyou!
UPDATE: Added full code, sorry!
It looks like your .forEach() is the root of the problem. The parameters of a forEach are currentValue, index like this: array.forEach(function(currentValue, index) {}); but it looks like you're using them in the opposite way
Try rewriting that iteration to this:
ytFill.forEach(function(v, i) {
console.log(i);
ytdlOptions.append(new Option(v.fmt_quality, v.fmt_id));
});
Notice the difference in the order of v and i in the parameters.
Dears,
I have a function, to which i input JSON data
function getTotals(users){
users = data;
allUsers = users.length;
active = 0;
women = 0;
men = 0;
lastActive = 0;
for (elm in users){
if (users[elm].active){
active++;
if (users[elm].gender == "Female"){
women++;
} else if (users[elm].gender == "Male") {
men++;
} else if (users[elm].last_login){
var lastLogin = new Date (users[elm].last_login);
var lastMonths = lastLogin.getMonth()-6;
var lastYears = lastLogin.getFullYear();
//console.log(lastYears);
if (lastMonths <6 && lastMonths > -6 && lastYears >= lastLogin.getFullYear()-1){
lastActive++;
}
}
}
}
return {allUsers : allUsers, active : active, women : women, men : men, lastActive : lastActive};}
but i cannot display the values, when i do following:
var listOfUsers = document.createElement('p');
listOfUsers.textContent = "Liczba wszystkich użytkowników: "+allUsers;
document.querySelector("#row1 > div").appendChild(listOfUsers);
var listOfActive = document.createElement('p');
listOfActive.textContent = "Liczba aktywnych użytkowników: "+active;
document.querySelector("#row2 > div").appendChild(listOfActive);
var listOfWomen = document.createElement('p');
listOfWomen.textContent = "Liczba aktywnych kobiet: "+women;
document.querySelector("#row3 > div").appendChild(listOfWomen);
var listOfMen = document.createElement('p');
listOfMen.textContent = "Liczba aktywnych mężczyzn: "+men;
document.querySelector("#row4 > div").appendChild(listOfMen);
var listOfLastActv = document.createElement('p');
listOfLastActv.textContent = "Liczba aktywnych (ost 6 mcy): "+lastActive;
document.querySelector("#row5 > div").appendChild(listOfLastActv);
When i do following (found here in other questions):
var getTotalUsers = new getTotal();
var allUsers = getTotalUsers.allUsers;
var active = getTotalUsers.active;
var women = getTotalUsers.women;
var men = getTotalUsers.men;
var lastActive = getTotalUsers.lastActive;
I get undefined as a result. I do not know how to fix this issue, as in next part of js, i will need to display list of active users.
new Promise() returns results asynchronously. You can either chain .then() or use async/await to get expected result
function httpGet() {
return new Promise(function(resolve) {
setTimeout(function() {
resolve([{a:1}, {b:2}, {c:3}])
}, Math.floor(Math.random() * 1200))
})
}
async function getTotals() {
const users = await httpGet();
console.log(users);
}
getTotals();
function httpGet() {
return new Promise(function(resolve) {
setTimeout(function() {
resolve([{a:1}, {b:2}, {c:3}])
}, Math.floor(Math.random() * 1200))
})
}
function getTotals() {
const data = httpGet();
data.then(function(users) {
console.log(users)
})
.catch(function(err) {
console.log(err)
})
}
getTotals();