Why the undefined gets outputted instead of the object properties.
Created a function, defined setters for the parameters and function to output the string consisting of the parameters.
Below is the snippet for the app.js file.
// app.js
function Fruit(theColor, sweetness, theName, theOrigin) {
//properties
this.theColor = theColor;
this.sweetness = sweetness;
this.theName = theName;
this.theOrigin = theOrigin;
//functions
this.showName = function () {
console.log("This is a " + this.theName);
};
this.showLand = function () {
this.theOrigin.forEach(function (arg) {
console.log("Grown in: " + arg);
});
};
}
var mango = new Fruit("Yellow", 9, "Mango", ["India", "Central America"]);
console.log(mango.showName() + " " + mango.showLand());
This line:
console.log(mango.showName() + " " + mango.showLand());
calls those functions, then outputs their return values with a space between them. Neither showNames nor showLand returns anything, and so calling them gives you the result undefined.
If you just want to call those, just call them, without using console.log to output their result. E.g., replace:
console.log(mango.showName() + " " + mango.showLand());
with
mango.showName();
mango.showLand();
If you want them to return, rather than display, their result, edit them to do so. You'll have to decide how you want showLand to separate lines (e.g., with a \n, or by returning an array, etc.).
For instance, this showName will return a string, and showLand will return an array:
//functions
this.showName = function () {
return "This is a " + this.theName;
};
this.showLand = function () {
return this.theOrigin.map(function (arg) {
return "Grown in: " + arg;
});
};
which you could then call like this:
console.log(mango.showName() + ". " + mango.showLand().join(", "));
Live Example:
function Fruit(theColor, sweetness, theName, theOrigin) {
//properties
this.theColor = theColor;
this.sweetness = sweetness;
this.theName = theName;
this.theOrigin = theOrigin;
//functions
this.showName = function () {
return "This is a " + this.theName;
};
this.showLand = function () {
return this.theOrigin.map(function (arg) {
return "Grown in: " + arg;
});
};
}
var mango = new Fruit("Yellow", 9, "Mango", ["India", "Central America"]);
console.log(mango.showName() + ". " + mango.showLand().join(", "));
Related
I created this function to replace value in a string and call functions whose name is the value.
$(function() {
var str = "Homer drank {{countBeers}} beers";
function countBeers() {
console.log(this);
return 10 + 10;
}
function convert(str) {
console.log(this);
str = "'" + str.replace(/{{(.*?)}}/g, "' + $1.call(this) + '") + "'";
OR
str = "'" + str.replace(/{{(.*?)}}/g, "' + $1(this) + '") + "'";
return eval(str);
}
var output = convert.call(this, str);
$('body').append(output); //Homer drank 20 beers
});
This seems to work fine, but I would not use eval.
You can do it any other way?
Thank you
You could use an object with the function.
function convert(str) {
return str.replace(/{{(.*?)}}/g, function (_, f) {
return op[f] ? op[f]() : f;
});
}
var str = "Homer drank {{countBeers}} beers",
op = { countBeers: function () { return 10 + 10; } };
console.log(convert(str));
In the code below I would like to pass a reference to a function that resides on the parent scope to the nested scope of the function "nested", so I can call the function on the parent scope from the nested function. I tried passing it in as a parameter but it doesn't work. I'm just learning/messing around with nested closures and wondering if this could be done.
I would like to have the syntax for calling nested be: callme.nested()
var obj = function(val){
var access = val;
var apex = 0;
return {
callme : (function(siblyng){
var privatevar = 2;
return {
nested : function(){
privatevar++;
apex = privatevar;
return access + " " + privatevar + " " + siblyng("child");
}
}
})(this.sibling),
assess : function(){
return apex + " " + this.sibling("parent");
},
sibling : function(val){
return "returned from " + val + " scope";
}
}
}
var objref = obj(true);
console.log(objref.callme.nested());
console.log(objref.callme.nested());
console.log(objref.callme.nested());
console.log(objref.assess());
console.log(objref.sibling('global'));
If I understood you well, you can do it like so
var obj = function(val){
var access = val;
var apex = 0;
var ret;
return (ret = {
callme : function() {
var privatevar = 2;
return {
nested : function(){
privatevar++;
apex = privatevar;
return access + " " + privatevar + " " + ret.sibling("child");
}
};
}(),
assess : function(){
return apex + " " + this.sibling("parent");
},
sibling : function(val){
return "returned from " + val + " scope";
}
});
};
var objref = obj(true);
console.log(objref.callme.nested());
console.log(objref.callme.nested());
console.log(objref.callme.nested());
console.log(objref.assess());
console.log(objref.sibling('global'));
Your this in the following code was pointing to the global Window object and so it was not able to find the method. You could have directly called this.sibling in your nested method without the need of passing it.
callme : (function(siblyng){
var privatevar = 2;
return {
nested : function(){
privatevar++;
apex = privatevar;
return access + " " + privatevar + " " + siblyng("child");
}
}
})(this.sibling),
What I have,
var oldUsers = [{
"SID": "S-12",
"Username": "bring.on",
"firstname": "bring",
"lastname": "on",
"email": "emasdklhsjas#gmnailasd.com"
// and so on... 10 more properties
}, {
"SID": "S-13",
"Username": "bring.on1",
"firstname": "bring",
"lastname": "on1",
"email": "sdf#gmnailasd.com"
// and so on... 10 more properties
},
// n numbers of more users...];
What I want,
var newUsers = [{ FullName : "bring on - emasdklhsjas#gmnailasd.com",
value : S-12
},
{ FullName : "bring on1 - sdf#gmnailasd.com",
value : S-13
}, // more users with same properties as abvove
];
What I tried but failed,
var newUsers = $.each(oldUser, function () {
return u = {
value : this.SID,
FullName : this.firstname + " " + this.lastname + " - " + this.email,
};
});
It needs to work on IE-8+ not sure what I am doing wrong really.
All I want is to reduce properties of object in array and get a new object.
Array.prototype.map() can be used to create new array using Plain old Vanilla JavaScript.
The map() method creates a new array with the results of calling a provided function on every element in this array
var newUsers = oldUser.map(function(obj){
return {
value : obj.SID,
FullName : obj.firstname + " " + obj.lastname + " - " + obj.email,
}
});
Note: It will work with IE9+
Using jQuery.map()
var newUsers = jQuery.map(oldUser, function(obj){
return {
value : obj.SID,
FullName : obj.firstname + " " + obj.lastname + " - " + obj.email,
}
});
Your problem is that the .each function doesn't return anything.
http://api.jquery.com/jquery.each/. It iterates over the collection of objects and performs and action on each one. This is different than the functional concept of the higher order function map, which is used to translate one collection into another. (JQuery has a map function too.)
To fix your problem you either need to do:
var newArray = []
var newUsers = $.each(oldUser, function () {
newArray.push ({
value : this.SID,
FullName : this.firstname + " " + this.lastname + " - " + this.email,
});
});
or
var newArray = $.map(oldUsers, function (u,i) {
return {
value : this.SID,
FullName : u.firstname + " " + u.lastname + " - " + u.email,
};
});
Personally, I would go with the second one, as it reduces the number of side effects in your code.
Edit: Apparently, map does not work in IE 8, so the top one is the more correct approach.
Try the following:
var newUsers = [];
$.each(oldUser, function () {
newUsers.push({
value : this.SID,
FullName : this.firstname + " " + this.lastname + " - " + this.email,
});
});
Here is a fiddle for it. Check your console log for the outcome when you run the fiddle.
try this!
var newArr= [];
$.each(users, function (index , user) {
newArr.push({
value : user.SID,
FullName : user.firstname + " " + user.lastname + " - " + user.email,
});
});
Your object is an array of objects, so make use of Array map method:var result = oldUsers.map(function(e){
return { Fullname : e.firstname + e.lastname, value : e['SID']};
});
I have two Jquery function. How do I set the execution order so that function B would only be called after function A, (reason behind is that Function A set a value to a variable IdstoExclude that is getting passed as a parameter to function B.
Below is what i tried but no luck:
var IDstoExclude = "123";
callListService('getArticleTypelistById', 'Atid', 87, 5, '#MainStory', '#tmplFeaturePanel', IDstoExclude);
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude);
function callListService(webServiceName, parameterName, parameterValue, noOfItems, domElement, templName, exclIDs) {
//set a default value for the template name * exclIDs
templName = templName || "#FeaturedSubStories";
//exclIDs = exclIDs || "123,12";
var inputParameters = webServiceName.toLowerCase() + ':' + parameterName.toLowerCase() + ':' + parameterValue + ':noofitems:' + noOfItems + ':excludeids:' + exclIDs;
var clientcode = getCryptoToken(inputParameters);
//Build JSONp query
eval("data={" + parameterName.toLowerCase() + ":" + parameterValue + ", noofitems: " + noOfItems + ", excludeids:" + exclIDs + ", clientcode:'" + clientcode + "' }");
$.getJSON('https://abc.com/Service.svc/' + webServiceName + '?callback=?', data, function (data2) {
var template = $.templates(templName);
var htmlOutput = template.render(data2);
$(domElement).append(htmlOutput);
IDstoExclude = data2.IdsInThisList;
});
Tried below but no luck: var IDstoExclude = "123";
function callService1() {
return $.ajax()
.then(function(response) {
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude);
});
}
function callService2() {
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude)
}
$.when(callService1()).then(callService2);
For this solution to work as you expect your code should look like something below:
function callService1(p1, p2, ...) {
return $.ajax(...)
.then(function(response) {
return something;
});
}
function callService2(something_from_s1) {
// work with something_from_s1 var
}
$.when(callService1(...)).then(callService2);
References:
http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/
http://api.jquery.com/category/deferred-object/
http://api.jquery.com/deferred.then/
I am new to JS and have created this original problem from CodeAcademy which works. Now I wanted to put my flock of sheep into an object and access it using my sheepCounter function. I am new to accessing key/values from an object and am stuck on what I am doing wrong. Thanks in advance!
Original Code
var sheepCounter = function (numSheep, monthNumber, monthsToPrint) {
for (monthNumber = monthNumber; monthNumber <= monthsToPrint; monthNumber++) {
numSheep *= 4;
console.log("There will be " + numSheep + " sheep after " + monthNumber + " month(s)!");
}
return numSheep;
}
New Code:
var flock = {
sheep: 4,
month: 1,
totalMonths: 12
};
var sheepCounter = function (counter) {
for (counter[month] = counter[month]; counter[month] <= counter[totalMonths]; counter[month]++) {
numSheep *= 4;
console.log("There will be " + counter[sheep] + " sheep after " + counter[month] + " month(s)!");
}
return counter[sheep];
}
Found the error in your solution:
var sheepCounter = function (counter) {
for (counter['month'] = counter['month']; counter['month'] <= counter['totalMonths']; counter['month']++) {
counter['sheep'] *= 4;
console.log("There will be " + counter['sheep'] + " sheep after " + counter['month'] + " month(s)!");
}
return counter['sheep'];
}
You can access your Flock Object like so,
alert(flock.sheep); //4
If you have an array in an object, like
names: ['joe','tom','bob'];
You would access that like so,
alert(flock.names[0]); // joe
alert(flock.names[2]); // bob