How to get variable from different function [closed] - javascript

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
So what I'm trying to do is get a search term from one function getRandomVideo() and use it in a jQuery statement, so for example, get beethoven from the variable searches and use it as the search term to get back JSON information and append it to a div. I know next to nothing about jQuery so any help would be great thanks :)
<script type="text/javascript">
function getRandomVideo() {
var videos = [
'https://www.youtube.com/embed/kiTO7c_qeZs',
'https://www.youtube.com/embed/z4Hfv00eqoI',
'https://www.youtube.com/embed/7cdZYQB5ONE',
'https://www.youtube.com/embed/i1gE3nyQnKg',
];
var titles = [
'Beethoven - Music, Love and Wine',
'Mozart String Serenade No.13',
'Beethoven Sonata No. 31 in A Flat Major',
"Debussy - Children's Corner",
];
var images = [
"url('Assets/beethoven.jpg')",
"url('Assets/mozart.jpg')",
"url('Assets/beethoven.jpg')",
"url('Assets/debussy.jpg')",
]
var searches = [
'beethoven',
'mozart',
'beethoven',
'debussy',
]
var rand = Math.floor(Math.random()*videos.length);
var video = videos[rand];
var title = titles[rand];
var image = images[rand];
var search = searches[rand];
document.getElementById("songTitle").innerHTML = title;
document.getElementById("img").style.backgroundImage = image;
var htmlVideo = document.getElementById("randomVideo");
htmlVideo.src = video;
htmlVideo.onload=null;
return search
}
getRandomVideo();
$(document).ready(function(){
// Im not sure what to do here to get it to run when the page starts
// Get the value from our getRandomVideo()
var searchTerm = getRandomVideo();
var url = "http://api.trove.nla.gov.au/result?key=jja10ssv4950uh65&encoding=json&zone=newspaper&sortby=relevance&q=" + searchTerm + "&s=0&n=5&include=articletext,pdf&encoding=json&callback=?";
/*
* Perform the search using jQuery's getJSON method
* Requires the search URL
*/
console.log(url);
$.getJSON(url, function(data) {
$.each(data.response.zone[0].records.article, function(index, value) {
$("#output").append("<p>" + value.articleText +"</p>");
});
});
};
</script>

This should give you an idea as to how to accomplish this...
var getRandomVideo = (function(){
var _videos = [
'https://www.youtube.com/embed/kiTO7c_qeZs',
'https://www.youtube.com/embed/z4Hfv00eqoI',
'https://www.youtube.com/embed/7cdZYQB5ONE',
'https://www.youtube.com/embed/i1gE3nyQnKg',
];
var _titles = [
'Beethoven - Music, Love and Wine',
'Mozart String Serenade No.13',
'Beethoven Sonata No. 31 in A Flat Major',
"Debussy - Children's Corner",
];
var _images = [
"url('Assets/beethoven.jpg')",
"url('Assets/mozart.jpg')",
"url('Assets/beethoven.jpg')",
"url('Assets/debussy.jpg')",
];
var _searches = [
'beethoven',
'mozart',
'beethoven',
'debussy',
];
return {
videos: function(){ return _videos; },
titles: function(){ return _titles; },
images: function(){ return _images; },
searches: function(){ return _searches; }
};
})(); // this is the module pattern FYI
var rand = Math.floor(Math.random() * getRandomVideo.videos().length);
var video = getRandomVideo.videos()[rand];
var title = getRandomVideo.titles()[rand];
var image = getRandomVideo.images()[rand];
var search = getRandomVideo.searches()[rand];
document.getElementById("songTitle").innerHTML = title;
document.getElementById("img").style.backgroundImage = image;
var htmlVideo = document.getElementById("randomVideo");
In javascript, everything including variables are scoped by function so any variable declared inside a function such as...
function myFunction()
{
var a1 = "something";
}
var test = a1; // a1 would be undefined as it is out of scope of `myFunction()` so test would be too of course
By using the module pattern, you can expose properties/functions within the return{}; statement. NB: the underscores are just to identify private functions/objects etc ;)
Also if you were to do the below, you would be able to access a1 as it would cascade into global scope as it has not been declared...
function myFunction()
{
a1 = "something";
}
var test = a1; // a1 would be "something"
But I wouldn't suggest this... for a number of architectural reasons :-/

Related

Multiple search creteTextFinder app scrip [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I'm currently working on a project where I send data to a google sheet through app script.
I need to change the value of some data and used createTextFinder.
Thanks to #Mimi in this thread. But the fact is that I need to replace more than one text.
I need to change the text when the data is appending.
thanks in advance
Here is my code
function addUser(sheet) {
var FILE = SpreadsheetApp.openById("XXXXXXXXXXXXX");
var sheet = FILE.getSheetByName("Sheet1");
var id = "True";
var name = "FALSE";
var t1 = createTextFinder("TRUE").replaceAllWith("YES")
var t2 = createTextFinder("FALSE").replaceAllWith("NO")
sheet.appendRow([id,name]).t1.t2;
From I need to change the text when the data is appending., in this case, how about the following modification?
From:
var t1 = createTextFinder("TRUE").replaceAllWith("YES")
var t2 = createTextFinder("FALSE").replaceAllWith("NO")
sheet.appendRow([id,name]).t1.t2;
To:
var values = [id, name].map(e => {
var temp = e.toUpperCase();
return temp == "TRUE" ? "YES" : temp == "FALSE" ? "NO" : e;
});
sheet.appendRow(values);
For example, when you are required to use TextFinder, how about the following modification?
From
var t1 = createTextFinder("TRUE").replaceAllWith("YES")
var t2 = createTextFinder("FALSE").replaceAllWith("NO")
sheet.appendRow([id,name]).t1.t2;
To
sheet.appendRow([id, name]);
sheet.createTextFinder("TRUE").replaceAllWith("YES");
sheet.createTextFinder("FALSE").replaceAllWith("NO");
or, when you want to use TextFinder to the appended row, you can also the following modified script.
sheet.appendRow([id, name]);
// SpreadsheetApp.flush(); // This might be not required to be used.
const range = sheet.getRange(sheet.getLastRow(), 1, 1, 2);
range.createTextFinder("TRUE").replaceAllWith("YES");
range.createTextFinder("FALSE").replaceAllWith("NO");
Multiple Replacement
function addUser() {
const txtA = ['txt1', 'txt2', 'text3'];
const rplA = ['rpl1', 'rpl2', 'repl3'];
var ss = SpreadsheetApp.openById("XXXXXXXXXXXXX");
var sh = ss.getSheetByName("Sheet1");
txtA.forEach((t, i) => {
let f = sh.createTextFinder(t).findAll();
if (f) {
f.forEach(r => { r.setValue(r.getValue().replace(txtA[i], rplA[i])); });
}
});
}

Javascript Appending to 2-D Array

I am trying to append an array to an array. I am expecting the output to be something like:
[[Dep,POR],[14073,99.25],[14072,0.06]]
But I am getting:
Dep,POR,14073,99.25,14072,0.06
Here's what I have so far:
function get_historical() {
var well = document.getElementById('wellSelect');
var selected_well = well.options[well.selectedIndex].value;
var hist_json_obj = JSON.parse(Get("/get_historical/" + selected_well));
hist_por = ['Dep','POR'];
for (var item in hist_json_obj) {
if (hist_json_obj.hasOwnProperty(item)) {
var dep = hist_json_obj[item].dep;
var por = hist_json_obj[item].por;
var arr_por = [dep, parseFloat(por)];
hist_por.push(arr_por);
}
}
document.write(hist_por);
}
When you initialize hist_por, you want that to be a 2-D array whereas you currently have just a single array. So you would want to change its instantiation to:
hist_por = [['Dep','POR']]; // [[ ... ]] instead of [ ... ]
Also per #justrusty's answer, you need to JSON.stringify(hist_por) when you pass it to document.write(). This is the more important piece so his answer should be accepted.
So the whole code block would become:
function get_historical() {
var well = document.getElementById('wellSelect');
var selected_well = well.options[well.selectedIndex].value;
var hist_json_obj = JSON.parse(Get("/get_historical/" + selected_well));
hist_por = [['Dep','POR']];
for (var item in hist_json_obj) {
if (hist_json_obj.hasOwnProperty(item)) {
var dep = hist_json_obj[item].dep;
var por = hist_json_obj[item].por;
var arr_rop = [dep, parseFloat(por)];
hist_por.push(arr_por);
}
}
document.write(JSON.stringify(hist_por));
}
This may help you https://codepen.io/anon/pen/xQLzXx
var arr = ['foo','bar'];
var arr2 = ['baz', 'boo']
arr.push(arr2);
console.log(arr);
document.write(arr);
document.write("<br>");
document.write(JSON.stringify(arr));
It's basically just the way it writes it to document. If you log it in console you'll see the array appended. Or if you JSON.stringify() first it will show as you expect.
My advice is ALWAYS console.log() so you can see exactly how the data is structured
The others have already pointed out what the problem is (+ there's a typo in one of your variable names - arr_rop vs arr_por). Here's an ES6 version that will break in older browsers, for learning purposes:
function get_historical() {
const well = document.getElementById('wellSelect');
const selected_well = well.options[well.selectedIndex].value;
const hist_json_obj = JSON.parse(Get("/get_historical/" + selected_well));
const hist_por = Object.values(hist_json_obj).reduce(
(arr, item) => [...arr, [item.dep, +item.por]],
[["Dep", "POR"]]
);
document.write(JSON.stringify(hist_por));
}

Why is this JavaScript looping twice in Zapier?

Here is a video that shows what I'm struggling with.
Here is a high level description of the process, followed by the actual JavaScript code I've written.
PROCESS
I built 2 Zaps that each run like this:
STEP 1 - Trigger (Cognito Form, which has repeating sections)
STEP 2 - JavaScript Code (which creates an Array of the form fields for ONE of the repeating sections, and separates them into individual strings using .split)
STEP 3 - Action (creates a ZOHO CRM Task for each string)
The first Zap runs on one of the sections of the form (Visits with Sales), and the second zap runs on a different section of the form (Visits without Sales). Each of these Zaps works fine on their own so I know the code is good, but I want to combine the two Zaps into one by combining the code.
I tried to combine by making five steps:
Trigger - Code1 - Zoho1 - Code2 - Zoho2
but the Zoho2 Tasks were each repeated
I then tried to re-order the five steps:
Trigger - Code1 - Code2 - Zoho1 - Zoho2
but now Zoho1 Tasks AND Zoho2 tasks were duplicated.
Finally I tried to combine ALL the JavaScript code into one:
Tigger - CombinedCode1+2 - Zoho 1 - Zoho2
but only the strings from Arrays in "Code2" are available to me when I go to map them in Zoho1.
CODE:
if (inputData.stringVSAccount == null) {
var listVSAccountArray = [];
var listVSUnitsArray = [];
var listVSPriceArray = [];
var listVSNotesArray = [];
var listVSVisitCallArray = [];
} else {
var listVSAccountArray = inputData.stringVSAccount.split(",");
var listVSUnitsArray = inputData.stringVSUnits.split(",");
var listVSPriceArray = inputData.stringVSPrice.split(",");
var listVSNotesArray = inputData.stringVSNotes.split(",");
var listVSVisitCallArray = inputData.stringVSVisitCall.split(",");
}
var output = [];
var arrayNos = listVSAccountArray.length;
var i = 0;
do {
var thisItemVSAccount = new String(listVSAccountArray[i]);
var thisItemVSUnits = new String(listVSUnitsArray[i]);
var thisItemVSPrice = new String(listVSPriceArray[i]);
var thisItemVSNotes = new String(listVSNotesArray[i]);
var thisItemVSVisitCall = new String(listVSVisitCallArray[i]);
var thisItemObj = {};
thisItemObj.itemVSAccount = thisItemVSAccount;
thisItemObj.itemVSUnits = thisItemVSUnits;
thisItemObj.itemVSPrice = thisItemVSPrice;
thisItemObj.itemVSNotes = thisItemVSNotes;
thisItemObj.itemVSVisitCall = thisItemVSVisitCall;
output.push({ thisItemObj });
i++;
} while (i < arrayNos);
//This is where the second zaps code is pasted in the combined version
if (inputData.stringOVAccount == null) {
var listOVAccountArray = [];
var listOVNotesArray = [];
var listOVVisitCallArray = [];
} else {
var listOVAccountArray = inputData.stringOVAccount.split(",");
var listOVNotesArray = inputData.stringOVNotes.split(",");
var listOVVisitCallArray = inputData.stringOVVisitCall.split(",");
}
var output = [];
var arrayNos = listOVAccountArray.length;
var i = 0;
do {
var thisItemOVAccount = new String(listOVAccountArray[i]);
var thisItemOVNotes = new String(listOVNotesArray[i]);
var thisItemOVVisitCall = new String(listOVVisitCallArray[i]);
var thisItemObj = {};
thisItemObj.itemOVAccount = thisItemOVAccount;
thisItemObj.itemOVNotes = thisItemOVNotes;
thisItemObj.itemOVVisitCall = thisItemOVVisitCall;
output.push({ thisItemObj });
i++;
} while (i < arrayNos);
I just started learning JavaScript this week, and sense that I am missing something obvious, perhaps a set of brackets. Thanks for any assistance
David here, from the Zapier Platform team. You're running into a confusing and largely undocumented feature where items after a code step run for each item returned. This is usually desired behavior - when you return 3 submissions you want to create 3 records.
In your case, it's also running subsequent unrelated actions multiple times, which sounds like it's undesired. In that case, it might be easier to have 2 zaps. Or, if "Zoho2" only ever happens once, put it first and let the branch happen downstream.
Separately, I've got some unsolicited javascript advice (since you mentioned you're a beginner). Check out Array.forEach (docs), which will let you iterate through arrays without having to manage as many variables (your own i every time). Also, try to use let and const over var when possible - it keeps your variables scoped as small as possible so you don't accidentally leak values into other areas.
​Let me know if you've got any other questions!
Just a note - you are declaring the same array variable output in both segments of your code block - the second declaration will be ignored.
Use the .forEach() method to iterate over your arrays, it will significantly cleanup you code. You also don't need to painstakingly construct the objects to be pushed into the output arrays.
This may not fix your issue but the code is far easier on the eye.
var listVSAccountArray = [],
listVSUnitsArray = [],
listVSPriceArray = [],
listVSNotesArray = [],
listVSVisitCallArray = [],
output = [];
if (typeof inputData.stringVSAccount === 'string') {
listVSAccountArray = inputData.stringVSAccount.split(',');
listVSUnitsArray = inputData.stringVSUnits.split(',');
listVSPriceArray = inputData.stringVSPrice.split(',');
listVSNotesArray = inputData.stringVSNotes.split(',');
listVSVisitCallArray = inputData.stringVSVisitCall.split(',');
}
// iterate over the array using forEach()
listVSAccountArray.forEach(function(elem, index){
// elem is listVSAccountArray[index]
output.push({
itemVSAccount: elem,
itemVSUnits: listVSUnitsArray[index],
itemVSPrice: listVSPriceArray[index],
itemVSNotes: listVSNotesArray[index],
itemVSVisitCall: listVSVisitCallArray[index]
})
})
//This is where the second zaps code is pasted in the combined version
var listOVAccountArray = [],
listOVNotesArray = [],
listOVVisitCallArray = [],
output_two = []; // changed the name of the second output array
if (typeof inputData.stringOVAccount === 'string') {
listOVAccountArray = inputData.stringOVAccount.split(',');
listOVNotesArray = inputData.stringOVNotes.split(',');
listOVVisitCallArray = inputData.stringOVVisitCall.split(',');
}
// iterate over the array using forEach()
listOVAccountArray.forEach(function(elem, index){
// elem is listOVAccountArray[index]
output_two.push({
itemOVAccount: elem,
itemOVNotes: listOVNotesArray[index],
itemOVVisitCall: listOVVisitCallArray[index]
});
});

How do I move an object from one array to another?

I'm trying to move an object from one array(triviaDataArray) to another(answeredQuestions). I've replaced the actual questions with numbers to shorten code. When I run this code it seems to remove a position in the triviaDataArray, and adds one to the answeredQuestion array. But it doesn't seem to remove the correct one. When a new question is loaded it sometimes repeats itself, which is not what I want. I want it to ask a question, and then when it is answered move it to the answeredQuestion array.
I can only use JavaScript. Can someone please help me. I've been struggling with this for quite some time.
This portion is from a data reader file I have to load a random question and it's answers from an array and the second is to open the array.
TriviaDataRecords.prototype.loadRandomRecord = function () {
this.position = Math.floor(Math.random() * this.records.length);
};
function openTriviaRecords(triviaData) {
return new TriviaDataRecords(triviaData);
}
global arrays and variables
var triviaDataArray = [1, 2, 3, 4, 5, 6, 7]
var answeredQuestions = []
var triviaRecords = openTriviaRecords(triviaDataArray);
function that loads a question and files the fields of the html.
function loadQuestion(){
var randomRecord = triviaRecords.loadRandomRecord();
var buttonA = document.getElementById("answer1");
var buttonB = document.getElementById("answer2");
var buttonC = document.getElementById("answer3");
var buttonD = document.getElementById("answer4");
var buttonE = document.getElementById("answer5");
document.getElementById('question').innerHTML = triviaRecords.getQuestion();
document.getElementById('answer1').innerHTML = triviaRecords.getAnswerA();
document.getElementById('answer2').innerHTML = triviaRecords.getAnswerB();
document.getElementById('answer3').innerHTML = triviaRecords.getAnswerC();
document.getElementById('answer4').innerHTML = triviaRecords.getAnswerD();
document.getElementById('answer5').innerHTML = triviaRecords.getAnswerE();
portion where I'm trying to move the question from one array to another.
var index = triviaDataArray.indexOf(randomRecord);
if (index == -1) {
triviaDataArray.splice(randomRecord, 1);
answeredQuestions.push(randomRecord);
}

Create objects dynamically with loop using JavaScript [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I was hoping someone could point me in the right direction.
I'm basically trying to build an OOP solution to dynamically generate a lot of objects based on a class and then to be able to run methods associated to each object via the class methods.
Below is my un-dynamic code.
// Create videoObject class
function videoObject(videoTag, videoNum){
this.videoTag = videoTag;
this.videoNum = videoNum;
this.videoTagHref = videoTag.attr("href");
this.videoId = function(videoTag){
};
this.addAttrId = function(videoNum){
};
this.printObjectInfo = function(videoId){
};
this.embedVideo = function(videoId, videoTag, videoNum){
};
this.buildControls = function(videoTag){
};
};
// Manually create two objects and run class methods
var newVideo1 = new videoObject($('.yt-player-0'), 0);
newVideo1.videoId();
newVideo1.addAttrId();
newVideo1.embedVideo();
newVideo1.buildControls();
var newVideo2 = new videoObject($('.yt-player-1'), 1);
newVideo2.videoId();
newVideo2.addAttrId();
newVideo2.embedVideo();
newVideo2.buildControls();
// I want to somehow create newVideo1 and newVideo2 dynamically inside a loop like below
var length = $('.yt-player').length;
for (var i = 0; i < length; i++) {
}
Any help you guys could give me would be much appreciated.
Thanks,
Tom
I would try this (untested):
// Create videoObject class
function videoObject(videoTag, videoNum){
this.videoTag = videoTag;
this.videoNum = videoNum;
this.videoTagHref = videoTag.attr("href");
this.videoId = function(videoTag){
};
this.addAttrId = function(videoNum){
};
this.printObjectInfo = function(videoId){
};
this.embedVideo = function(videoId, videoTag, videoNum){
};
this.buildControls = function(videoTag){
};
// call these methods in your constructor instead of repeatedly from elsewhere
this.videoId();
this.addAttrId();
this.embedVideo();
this.buildControls();
// send back a reference to this newly created video object to the loop
return this;
};
// create an array of video object references
var videoObjectReferences = [];
for (var i=0;i<10;i++){
// building ten video objects here, with ids of: yt-player-0, yt-player-1, etc.
// build a selector to reference them via id, not by class with a dot as you have in your question
var sel = String("#yt-player-" + i);
// create the object and store a reference to the video object so you can do something with it later
var newVid = new videoObject($(sel), i);
// build list of references
videoObjectReferences.push(newVid);
}
var videos = [2];
for(var i = 0; i < 2; i++){
videos[i] = new videoObject($('.yt-player-0'), 0);
/*Extra method calls here*/
}
If you always want to initialize your object with those extra method calls, you may want to consider having your object constructor handle that for you. Then your client code would be much cleaner.

Categories

Resources