How can I send an array between different scopes? - javascript

I created the array in the scope of $(document).ready(function(){});
for example:
$(document).ready(function(){
$.getJSON("data.json", function(json) {
function Question(q,correactA,array)
{
this.question=q;
this.correct_a=correactA;
this.answers=array;
}
multiQ= new Array();
for (i=0;i<5;i++)
{
var q = json.questions[i].question;
var corA= json.questions[i].correct_answer;
var a = json.questions[i].answers;
var aString = "";
Object.keys(a).forEach(function (k) {aString += a[k] ;})
multiQ[i]=new Question(q,corA,aString);
}
for (i=0;i<5;i++)
{
console.log(multiQ[i]);
}
});
});
Now I want to send the multiQ array to external var outside the scope.
How can I do it?

Declare
var multiQ= new Array();
outside $(document).ready function:
var multiQ= new Array();
$(document).ready(function(){
$.getJSON("data.json", function(json) {
function Question(q,correactA,array)
{
this.question=q;
this.correct_a=correactA;
this.answers=array;
}
for (i=0;i<5;i++)
{
var q = json.questions[i].question;
var corA= json.questions[i].correct_answer;
var a = json.questions[i].answers;
var aString = "";
Object.keys(a).forEach(function (k) {aString += a[k] ;})
multiQ[i]=new Question(q,corA,aString);
}
for (i=0;i<5;i++)
{
console.log(multiQ[i]);
}
});
});

It's very ugly, but you could assign a global getter inside the document.ready. For example:
var multiQ = new Array();
window.getMultiQ = function() { return multiQ; }
Then outside of document ready, you could call "var q = getMultiQ();"
Again, this is very ugly and would lead to unmaintainable code very fast. Most likely, there's an easier/cleaner way to accomplish what you're trying to do.

Related

Reduce code duplication using javascript oop

I have a javascript code which contains more number of functions. inside each functions code looks similar. Is there any way to reduce and optimize the code using javascript oop. So my script goes like this.
function cal_a() {
var a_list = [];
function fetch_dom() {
var a = document.getElementById("pOne");
a.innerHTML = "Hello";
a_list.push("Hello");
}
fetch_dom();
}
function cal_b() {
var b_list = [];
function fetch_dom() {
var b = document.getElementById("pTwo");
b.innerHTML = "World";
b_list.push("World");
}
fetch_dom();
}
cal_a();
cal_b();
//..
//..
//..
//cal_z();
HTML code looks
<p id="pOne"></p>
<p id="pTwo"></p>
Please pardon me if the question is wrong. Thanks in advance.
I have to say the list doesn't do anything here
function cal(id, text) {
var list = [];
function fetch_dom() {
var el = document.getElementById(id);
el.innerHTML = text;
list.push(text);
}
fetch_dom();
}
cal('id', 'text');
Sure, pull out the common parts and make a function which returns a function.
function make_cal(elem_id, text) {
return function() {
var list = [];
function fetch_dom() {
var b = document.getElementById(elem_id);
b.innerHTML = text;
list.push(text);
}
fetch_dom();
}
}
let cal_a = make_cal("pOne", "Hello");
let cal_b = make_cal("pTwo", "World");
The fetchDom is better to be placed on object constructor:
function Cal(elClass, text) {
this.list = [];
this.elClass = elClass;
this.text = text;
}
Cal.prototype.fetchDom = function() {
var el = document.getElementById(this.elClass);
el.innerHTML = this.text;
this.list.push(el);
};
var calA = new Cal("pOne", "Hello");
var calB = new Cal("pTwo", "World");
calA.fetchDom();
calB.fetchDom();
Then you can access your lists by:
calA.list;
calB.list;

How to combine 4 the same functions into one new function that can be reused

I made some functions, but they are all doing approximately the same thing.
I would like to combine those functions into one new function that can be reused in case i need one more new function like this.. Is it possible to do so or am i just wasting your and my time?
Here is the code:
function getBinding(selectedBinding) {
var b = elems.binding;
var selectedBinding = b.options[b.selectedIndex].value;
return selectedBinding;
}
// Getting the holes value
function getHoles(selectedHoles) {
var h = elems.holes;
var selectedHoles = h.options[h.selectedIndex].value;
return selectedHoles;
}
// Getting the paper weight value
function getPaperWeight(selectedPaperWeight) {
var pW = elems.paperWeight;
var selectedPaperWeight = pW.options[pW.selectedIndex].value;
return selectedPaperWeight;
}
// Getting the staples value
function getStaples(selectedStapling) {
var s = elems.stapling;
var selectedStapling = s.options[s.selectedIndex].value;
return selectedStapling;
}
any suggestions?
Thanks a lot!
You could take the element as parameter.
function getValue(element) {
var e = elems[element];
return e.options[e.selectedIndex].value;
}
I would get the prop type as parameters -
function selectByPropAndIndex(prop){
var elemByProp = elems[prop];
var selected= elemByProp.options[elemByProp.selectedIndex].value;
return selected;
}
You can use partial application to create this kind of functions:
function getItems(elementType) {
return function(elements) {
var items = elements[elementType];
return items.options[items.selectedIndex].value;
};
}
var getBinding = getItems('binding');
var getHoles = getItems('holes');
var getPaperWeight = getItems('paperWeight');
var getStaples = getItems('stapling');
Usage:
getBinding(elems);
You can try this:
function getSelectedProperty(property) {
var elem = elems[property];
return elem.options[elem.selectedIndex].value;
}
Note also that your original code has some problem. The parameters are useless because you are defining a new variable inside each function that would override the parameter name because you gave it the same name. As an example:
function foo(x) {
var x = 5; // this x is not the same as the parameter x
}
function getBinding(selectedElement, type) {
switch(type) {
case binding:
var element = elems.binding;
break;
case hole:
var element = elems.holes;
break;
case paper:
var element = elems.paperWeight;
break;
case staples:
var element = elems.stapling;
break;
}
var selectedElement = element.options[element.selectedIndex].value;
return selectedElement;
}
Something like getByKey?
//
function getValueByKey(key) {
var elem = elems[key];
var optionValue = elem.options[elem.selectedIndex].value;
return optionValue;
}
This is how i fixed it!
function getValue(selector){
return parseInt(selector.options[selector.selectedIndex].value);
};
Thanks all!

Adding numbers in an object is not working as expected in JS

I created an object with Int values and some functions in js as below
var obj = function (int1,int2,int3){
this.int1=int1;
this.int2=int2;
this.int3=int3;
this.add= (function (){
return parseInt(int1)+parseInt(int2)+parseInt(int3)
}());
When I execute the code
var a= new obj(1,2,3);
console.log(a.add);
The Answer is
NaN
Type of all the int1,int2.int3,add is Number.
Whats the problem with My code & How to correct it
You need a instance of the function with new operator and you could skip parseInt, which works better with a given base.
var Obj = function (int1, int2, int3) {
this.int1 = int1;
this.int2 = int2;
this.int3 = int3;
this.add = function () {
return this.int1 + this.int2 + this.int3;
}
},
instance = new Obj(1, 2, 3);
console.log(instance.add());
Try this:
var obj = function(int1, int2, int3) {
this.int1 = int1;
this.int2 = int2;
this.int3 = int3;
this.add = function() {
return parseInt(int1) + parseInt(int2) + parseInt(int3)
}};
And, Call above as:
var a = new obj(1, 2, 3);
console.log(a.add());
run this code:
var obj = function (int1, int2, int3) {
this.int1 = int1;
this.int2 = int2;
this.int3 = int3;
this.add = (function () {
return parseInt(int1) + parseInt(int2) + parseInt(int3)
} ())
};
var a = new obj(1,2,3);
console.log(a.add); // 6
your code lost a }
Try this it's working fine :
var obj = function (int1,int2,int3){
this.int1=int1;
this.int2=int2;
this.int3=int3;
this.add= (function (){
return parseInt(int1)+parseInt(int2)+parseInt(int3)
}())
}
var a= new obj(1,2,3);
console.log(a.add); // 6
Working fiddle :
https://jsfiddle.net/90ku8qae/
Update :
You forgot to add the closing bracket for the function obj. I just added and everything is working fine now.

Asynchronous Function in Iteration - javascript

I am trying not to replicate code and loop over a a function in d3 that is asynchronous. Here is some code
Since d3.text is asynchronous , I am not able to use the index u in a correct way to append objects to the DOM. How should I go about this? I need the loop to go to next iteration once d3.text finished
for(var u in urls) {
console.log(u);
var url = "interest_points/" + urls[u] + ".csv";
var data_gpBy_month = {};
var sortable_month = []
d3.text(url, function(text) {
// some code...
var data = d3.csv.parseRows(text).map(function(row) {
//some code...
});
//some code
});
}
Something like this (fiddle: http://jsfiddle.net/EYAYT/2/) ?
var urls = ["asd", "asdasd", "Asdasfa"];
var currentUrlIndex = 0;
var getUrl = function(){
if (currentUrlIndex >= urls.length){
return null;
} else {
return "interest_points/" + urls[currentUrlIndex++] + ".csv";
}
}
var execd3Text = function(){
var url = getUrl();
if (url){
d3.text(url, function(text) {
//some code;;
execd3Text();
});
}
}
execd3Text();
The loop should simply become this:
for(var u in urls) { loadParseAndRender(u); }
All your existing logic then moves into loadParseAndRender, but at this point u will never get overridden. I.e, in fancy terms, it gets captured in the closure.
function loadParseAndRender(u) {
// the rest of your code
}
What David W suggested is the same thing as abive, but without creating a named function for it, you'd do this:
for(var _u in urls) {
(function(u) { // this is an anonymous function
// the rest of you code
})(_u) // this function gets called as soon as it's declared
}
If I understood properly:
function doSomething(array) {
var u = array.shift();
console.log(u);
var url = "interest_points/" + urls[u] + ".csv";
var data_gpBy_month = {};
var sortable_month = []
d3.text(url, function(text) {
// some code...
var data = d3.csv.parseRows(text).map(function(row) {
//some code...
});
//some code
if (array.length > 0)
doSomething(array);
});
doSomething(Object.keys(urls));

Javascript | Objects, Arrays and functions

may be you can help me. How can I create global object and function that return object values by id?
Example:
var chat = {
data : {
friends: {}
}
}
....
/*
JSON DATA RETURNED:
{"users": [{"friend_id":"62","name":"name","username":"admin","thumb":"images/avatar/thumb_7d41870512afee28d91.jpg","status":"HI4","isonline":""},{"friend_id":"66","name":"Another name","username":"regi","thumb":"images/avatar/thumb_d3fcc14e41c3a77aa712ae54.jpg","status":"Всем привет!","isonline":"avtbsl0a6dcelkq2bd578u1qt6"},{"friend_id":"2679","name":"My name","username":"Another","thumb":"images/avatar/thumb_41effb41eb1f969230.jpg","status":"","isonline":""}]}
*/
onSuccess: function(f){
chat.data.friends = {};
for(var i=0; i< f.users.length;i++){
chat.data.friends.push(f.users[i])
}
}
How can I create a new function (It will return values by friend_id)?
get_data_by_id: function (what, friend_id) {
/*obj.what = getfrom_globalobject(chat.data.friends???)*/
}
Example of use:
var friend_name = get_data_by_id(name, 62);
var friend_username = get_data_by_id(username, 62);
var friend_avatar = get_data_by_id(thumb, 62);
Try:
get_data_by_id: function (what, friend_id) {
return chat.data.friends[friend_id][what];
}
... but use it like:
var friend_name = get_data_by_id('name', 62);
...and set up the mapping with:
for(var i=0; i< f.users.length;i++){
chat.data.friends[f.users[i].friend_id] = f.users[i];
}
You cannot .push() to an object. Objects are key => value mappings, so you need to use char.data.friends[somekey] = f.users[i];
If you really just want a list with numeric keys, make x5fastchat.data.friends an array: x5fastchat.data.friends = [];
However, since you want to be able to access the elements by friend_id, do the following:
onSuccess: function(f){
x5fastchat.data.friends = {};
for(var i=0; i< f.users.length;i++){
chat.data.friends[f.users[i].friend_id] = f.users[i]
}
}
get_data_by_id: function (what, friend_id) {
obj[what] = chat.data.friends[friend_id][what];
}
Note the obj[what] instead of your original obj.what: When writing obj.what, what is handled like a string, so it's equal to obj['what'] - but since it's a function argument you want obj[what].
Take a look at the following code. You can simply copy paste it into an HTML file and open it. click "go" and you should see the result. let me know if I did not understand you correctly. :
<script>
myObj = { "field1" : { "key1a" : "value1a" }, "field2" : "value2" }
function go()
{
findField(myObj, ["field2"])
findField(myObj, ["field1","key1a"])
}
function findField( obj, fields)
{
var myVal = obj;
for ( var i in fields )
{
myVal = myVal[fields[i]]
}
alert("your value is [" + myVal + "]");
}
</script>
<button onclick="go()">Go</button>
I would recommend using the friend objects rather than getting them by id and name.
DATA = {"users": [{"friend_id":"62","name":"name","username":"admin","thumb":"images/avatar/thumb_7d41870512afee28d91.jpg","status":"HI4","isonline":""},{"friend_id":"66","name":"Another name","username":"regi","thumb":"images/avatar/thumb_d3fcc14e41c3a77aa712ae54.jpg","status":"Всем привет!","isonline":"avtbsl0a6dcelkq2bd578u1qt6"},{"friend_id":"2679","name":"My name","username":"Another","thumb":"images/avatar/thumb_41effb41eb1f969230.jpg","status":"","isonline":""}]}
// simple data store definition
Store = {items:{}};
NewStore = function(items){
var store = Object.create(Store);
store.items = items || {};
return store
};
Store.put = function(id, item){this.items[id] = item;};
Store.get = function(id){ return this.items[id]; };
Store.remove = function(id){ delete this.items[id]; };
Store.clear = function(){ this.items = {}; };
// example
var chat = {
data : {
friends : NewStore()
}
}
// after data loaded
chat.data.friends.clear();
for( var i = 0; i < DATA.users.length; i += 1 ){
var user = DATA.users[i];
chat.data.friends.put( user.friend_id, user );
}
getFriend = function(id){ return chat.data.friends.get( id ); }
var friend = getFriend(66);
console.log(friend.name);
console.log(friend.username);
console.log(friend.thumb);

Categories