Object oriented OOJS - javascript-objects

This code works to add up the marks, calculate average and determine if the student is pass/fail. But,can is it a correct Object-oriented technique and whether it can be done in a better way?
function Student(marks1, marks2, marks3, marks4, marks5, marks6) {
// To find the sum total of the marks obtained
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
alert(" Total Marks is " + sum);
console.log(" Total Marks is " + sum);
// To find the average of the marks
var average = sum / 6;
alert(" Average Marks is " + average);
console.log(" Average Marks is " + average);
// To check if the student has passed/failed
if (average > 60) {
alert("Student has passed the exam");
console.log("Student has passed the exam");
} else {
alert("Student has failed the exam");
console.log("Student has failed the exam");
}
}
var myStudent = new Student(58, 64, 78, 65, 66, 58);

Take a look at Introduction to Object-Oriented JavaScript to see how to code using an object-oriented approach to JavaScript.
Note: I would pass in the marks as an array instead of a list of arguments. If you want, you can change the constructor to accept an object, that way you can pass in a variable number of arguments.
function Student(args) {
this.name = args.name || 'Unknown';
this.marks = args.marks || [];
}
Student.prototype.constructor = Student;
Student.prototype.calcSum = function() {
return this.marks.reduce(function(sum, mark) {
return sum + mark;
}, 0);
}
Student.prototype.calcAvg = function() {
return this.calcSum() / this.marks.length;
}
Student.prototype.didPass = function() {
var type = this.calcAvg() > 60 ? 'passed' : 'failed';
return this.name + " has " + type + " the exam.";
}
Student.prototype.toString = function() {
return 'Student { name : "' + this.name + '", marks : [' + this.marks.join(', ') + '] }';
}
// Convienience function to print to the DOM.
function print() { document.body.innerHTML += '<p>' + [].join.call(arguments, ' ') + '</p>'; }
// Create a new student.
var jose = new Student({
name : 'Jose',
marks : [58, 64, 78, 65, 66, 58]
});
print("Total Marks:", jose.calcSum()); // Find the sum total of the marks obtained.
print("Average Marks:", jose.calcAvg()); // Find the average of the marks.
print(jose.didPass()); // Check if the student has passed/failed.
print(jose); // Implicitly call the toString() method.

Related

Stuck at a silly loop in controller

I have this function:
$scope.showCurrencyT = function(invCurrency){
for (i=0; i<2; i++) {
console.log("i is " +i);
if (parseInt($scope.pageInfo.currencies[i].currencyCode) === parseInt(invCurrency) ) {
console.log('passed '+ i + ' ' + $scope.pageInfo.currencies[i].currencyCode )
var symbol = $scope.pageInfo.currencies[i].symbol
console.log(symbol);
} else {
console.log(i +" else")
var symbol = invCurrency
}
}
console.log("final symbol is " + symbol)
return symbol
}
The '2' in loop can be $scope.pageInfo.currencies.length actually
The $scope.pageInfo.currencies object look like this:
[
{
"_id":"59e5d2ad57acbb22bce66482",
"name":"US Dollar",
"nameInOriginalLanguage":"US Dollar",
"nameStringId":"806c1313-a9f4-53bc-8f20-6897aae76d0a",
"symbol":"USD",
"currencyCode":"840",
"__v":0
},
{
"_id":"59e5d2ec57acbb22bce66484",
"name":"Turkish Lira",
"nameInOriginalLanguage":"Türk Lirası",
"nameStringId":"e072dece-4e18-d830-06b3-9e789a3b5240",
"symbol":"TRY",
"currencyCode":"949",
"__v":0
}
]
When I passing in view:
{{showCurrencyT("840")}}
I get in console:
final symbol is 840
but when I pass it {{showCurrencyT("949")}} I get final symbol is TRY
It should return USD for 840 and I don't understand what's going on!
You do not need to use for loop here, you can simply use array.find() method to find the exact matching value as follows,
$scope.showCurrencyT = function(invCurrency){
var result = $scope.pageInfo.currencies.find(t=>t.currencyCode === invCurrency);
return result.symbol;
}

local variable value is no passed to promise return function in protractor using bluebird

var index = 0;
sc.getCaseNumber().then(function (text) {
console.log("dddddddddddd" + text);
for (var i = 0; i <= caseCount; i++) {
var expectedPendingCases = casenum.summaries[i].urn;
console.log("case " + expectedPendingCases);
if (text == expectedPendingCases) {
console.log("inside--------1 " + text);
expect(text).toEqual(expectedPendingCases);
index = i + 1;
sjpCasesPendingDecisionPage.getSearchCaseNumber(index).then(function (text) {
console.log("inside loop" + text);
});
break;
}
}
});
console.log("Index--------"+index);
return promise.props({
urn: sc.getSearchCaseNumber(index)
aDays: sc.getSearchAgeDays(index),
prosec: sc.getSearchprosecutor(index),
plea: sc.getSearchReadyForDecision(index)
});
I am trying to match a case number with data in expectedPendingCases and
get the index value and find all the elements using this index value and return the promise
however ,
index value is defaulted to 0 even when the index value is changed
this value is not reflected in
return promise.props({
urn: sc.getSearchCaseNumber(index)

Can not save array in shared object as3

I have this code in my simple flash. I want to save name and score in my quiz. My code reference in this website http://www.mollyjameson.com/blog/local-flash-game-leaderboard-tutorial/
I want to make my code in just one actionscript. But I didn't success do it.
var m_FlashCookie = SharedObject.getLocal("LeaderboardExample");
var EntryName:String ="nama kamu";
var EntryScore:String ="nilai";
const NUM_SCORES_SAVED:int = 10;
inputBoxScore.text = EntryScore;
inputBoxName.text = EntryName
var latest_score_object:Object = {
name: EntryName,
score: EntryScore
};
var arr:Array;
arr = m_FlashCookie.data.storedArray
if ( arr == null)
{
arr = new Array();
}
arr.push( latest_score_object );
arr.sortOn("score", Array.NUMERIC | Array.DESCENDING);
if ( arr.length < NUM_SCORES_SAVED )
{
arr.pop();
}
btnSave.addEventListener(MouseEvent.CLICK, saveData);
function saveData(event:Event):void
{
m_FlashCookie.data.arr = arr;
m_FlashCookie.flush();
}
var myHTMLL:String = "";
var total_stored_scores:int = arr.length;
btnLoad.addEventListener(MouseEvent.CLICK, loadData);
function loadData(event:Event):void
{
for (var i:int = 0; i < total_stored_scores; ++i)
{
// loop through every entry, every entry has a "name" and "score" field as that's what we save.
var leaderboard_entry:Object = arr[i];
// is this the last score that was just entered last gamestate?
if ( leaderboard_entry == latest_score_object )
{
myHTMLL += (i+1) + ". <b><font color=\"#0002E5\">"+ leaderboard_entry.name + " " + leaderboard_entry.score +"</font></b><br>";
}
else
{
myHTMLL += (i+1) + ". "+ leaderboard_entry.name + " " + leaderboard_entry.score +"<br>";
}
}
myHTML.text = myHTMLL;
}
Can anybody help me?
You're saving the array as data.arr but reading the array as data.storedArray. You need to make them the same.
In other words, you've written this:
m_FlashCookie.data.arr = arr;
And when you load:
arr = m_FlashCookie.data.storedArray;
This clearly doesn't make sense: data.storedArray is never set, so it will never have a value, so you will always end up with a new empty array.
You need to use the same property on the shared object data. For example:
m_FlashCookie.data.storedArray = arr;
m_FlashCookie.flush();
Looking at your code, there's a number of other issues:
The latest score is immediately removed because arr.length < NUM_SAVED_SCORES is going to be true from the start, since arr starts out empty, and it then calls arr.pop() which will remove the latest entry that was just added. So the array is always empty.
It adds the score immediately with arr.push(latest_score_object) instead of waiting until the user clicks save, so the value of the input texts don't matter at all -- the saved values will always be "nama kamu" and "nilai".
The following fixes all the issues mentioned:
var leaderboard = SharedObject.getLocal("leaderboard");
const MAX_SAVED_SCORES:int = 10;
inputBoxName.text = "nama kamu";
inputBoxScore.text = "nilai";
var entries:Array = leaderboard.data.entries || [];
var latestEntry:Object;
displayScores();
btnLoad.addEventListener(MouseEvent.CLICK, loadClick);
btnSave.addEventListener(MouseEvent.CLICK, saveClick);
function loadClick(e:MouseEvent):void {
displayScores();
}
function saveClick(e:MouseEvent):void {
saveLatestScore();
displayScores();
}
function saveLatestScore():void {
// create the latest entry based on input texts
latestEntry = {
name: inputBoxName.text,
score: inputBoxScore.text
};
// add the entry and sort by score, highest to lowest
entries.push(latestEntry);
entries.sortOn("score", Array.NUMERIC | Array.DESCENDING);
// if reached the limit, remove lowest score
if (entries.length > MAX_SAVED_SCORES) {
entries.pop();
}
// store new sorted entries to shared object
leaderboard.data.entries = entries;
leaderboard.flush();
}
function displayScores():void {
var myHTMLL:String = "";
for (var i:int = 0; i < entries.length; ++i) {
// loop through every entry, every entry has a "name" and "score" field as that's what we save.
var entry:Object = entries[i];
// is this the last score that was just entered last gamestate?
if (entry == latestEntry)
myHTMLL += (i+1) + ". <b><font color=\"#0002E5\">"+ entry.name + " " + entry.score +"</font></b><br/>";
else
myHTMLL += (i+1) + ". "+ entry.name + " " + entry.score +"<br/>";
}
myHTML.htmlText = myHTMLL;
}

Angular: Combine array objects and combine values

I'm retrieving data with http.get.
This provides me with an array of objects like below:
[{
"id”:12345,
"resource_state":2,
"external_id”:”abscdgrft”,
"upload_id”:1234567,
"athlete":{
"id”:123456,
"resource_state":2,
"firstname”:”testname”,
"lastname”:”testlastname”,
"profile_medium”:”image/athlete/medium.png",
"profile":"image/athlete/large.png",
"city”:”testcity”,
"state”:”teststate”,
…
},
"name”:”test name“,
"distance":87223.1,
"moving_time":11026,
"elapsed_time":11173,
"total_elevation_gain":682.3,
…
}]
I would like to combine all those object based on the athlete.firstname + athlete.lastname.
So for example all objects with athlete first name Jim and last name Donalds I want to be combined in one object, the same goes for all the other names.
When combining the objects based on the full name, values like "distance", "moving_time", "elapsed_time" and "total_elevation_gain" needs to be summed.
I tried using the code below but the problem is that I can't get it to work with multiple values like I mention above.
This is working only with one value, distance for example:
var obj = {}; // Initialize the object
angular.forEach(data, function(value, key) {
if (value.start_date > firstdayOfWeek && value.start_date < lastdayOfWeek) {
if (obj[value.athlete.firstname + ' ' + value.athlete.lastname]) { // If already exists
obj[value.athlete.firstname + ' ' + value.athlete.lastname] += value.distance; // Add value to previous value
} else {
obj[value.athlete.firstname + ' ' + value.athlete.lastname] = value.distance; // Add in object
}
} else {
//do nothing
}
});
console.log(obj); // Result
When I modify it like this it is not working anymore.
var obj = {};
angular.forEach(data, function(value, key) {
//console.log(value);
if (value.start_date > startOfLastWeek && value.start_date < endOfLastWeek) {
//console.log(value);
if (obj[value.athlete.firstname + ' ' + value.athlete.lastname]) { // If already exists
obj[value.athlete.firstname + ' ' + value.athlete.lastname] += {
"profile" : value.athlete.profile,
"distance" : value.distance,
"moving_time" : value.moving_time,
"elapsed_time" : value.elapsed_time,
"total_elevation_gain" : value.total_elevation_gain,
}; // Add value to previous value
} else {
obj[value.athlete.firstname + ' ' + value.athlete.lastname] = {
"profile" : value.athlete.profile,
"distance" : value.distance,
"moving_time" : value.moving_time,
"elapsed_time" : value.elapsed_time,
"total_elevation_gain" : value.total_elevation_gain,
}; // Add in object
}
} else {
//do nothing
}
});
console.log(obj); // Result
Thanks!
try to add item by item... You can't add all with += { ... }:
var obj = {};
angular.forEach(data, function(value, key) {
//console.log(value);
if (value.start_date > startOfLastWeek && value.start_date < endOfLastWeek) {
//console.log(value);
if (obj[value.athlete.firstname + ' ' + value.athlete.lastname]) { // If already exists
var aux = obj[value.athlete.firstname + ' ' + value.athlete.lastname];
aux.profile += value.athlete.profile;
aux.distance += value.distance;
...
} else {
obj[value.athlete.firstname + ' ' + value.athlete.lastname] = {
"profile" : value.athlete.profile,
"distance" : value.distance,
"moving_time" : value.moving_time,
"elapsed_time" : value.elapsed_time,
"total_elevation_gain" : value.total_elevation_gain,
}; // Add in object
}
} else {
//do nothing
}
});
console.log(obj); // Result
Use underscore or lodash groupBy, map and reduce
with lodash:
_.chain(myArr).map(function(o) {
return {
fullname: o.athlete.firstname + ' ' + o.athlete.lastname,
distance: o.distance,
moving_time: o.moving_time,
elapsed_time: o.elapsed_time,
total_elevation_gain: o.total_elevation_gain
}
}).groupBy(function(o) {
return o.fullaname
}).map(function(d, fullname) {
var totals = _.reduce(d, function(result, run, n) {
result.moving_time += run.moving_time | 0
result.elapsed_time += run.elapsed_time | 0
result.total_elevation_gain += run.total_elevation_gain | 0
return result
}, {
moving_time: 0,
elapsed_time: 0,
total_elevation_gain: 0
})
totals.fullname = fullname
return totals
})

Formatting numbers in Angular.js

I have a variable in Angular.js that I should fill like that :
values.push({x: '' + d.x + 'h', y: d.y / 100})
d.x and d.y are numbers that I should display in a ndv3 multiBarChart.But I should format the numbers as if I have 2500, I obtain 2 500.How can I do it ?
I write Angularjs filters Example.jsfiddle
HTML File
<div>
<label >{{"4876931.19" | numberFilter}}</label>
</div>
App Js
angular.module('myApp', ['filters']);
Filter js
angular.module('filters', []).filter('numberFilter', [function () {
return function (number) {
if (!angular.isUndefined(number)) {
var parts = number.split(".");
var str = parts[0].toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1 ");
if(parts[1] !== undefined){
str+="."+parts[1];
}
return str;
}
};
}]);
Updated Code
Here is a small Javascript function which parses the provided number and format it to the desired output:
function formatNumber(str) {
var parts = (str + "").split("."),
main = parts[0],
len = main.length,
output = "",
i = len - 1;
while(i >= 0) {
output = main.charAt(i) + output;
if ((len - i) % 3 === 0 && i > 0) {
output = " " + output;
}
--i;
}
// put decimal part back
if (parts.length > 1) {
output += "." + parts[1];
}
return output;
}
Calling this function with the provided number:
formatNumber(4876931.19) // output will be: 4 876 931.19
function formatNumber(str) {
var parts = (str + "").split("."),
main = parts[0],
len = main.length,
output = "",
i = len - 1;
while(i >= 0) {
output = main.charAt(i) + output;
if ((len - i) % 3 === 0 && i > 0) {
output = " " + output;
}
--i;
}
// put decimal part back
if (parts.length > 1) {
output += "." + parts[1];
}
return output;
}
console.log(formatNumber(4876931.19))

Resources