Stuck at a silly loop in controller - angularjs

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;
}

Related

Execute methods sequence - React

I have written following code to get current user group Ids and later from that Ids I wanted to filter data from SharePoint list. First I want to execute
ServiceManager.getRemoteService().getCurrentUserGroups()
method. Once I get group Ids, I want to execute the next method. But unfortunately filter part of the REST query is blank because
this.groupIdString
is blank. This may be because both methods are executed same time. I'm new to React and I want to know is there any best approach to manage this scenario. Basically I want to execute the methods in the order I write.
public componentDidMount() {
this.groupIdString= "";
ServiceManager.getRemoteService().getCurrentUserGroups(this.props.siteUrl, "/_api/web/currentuser/groups").then((value) => {
if (value[0]) {
for (let i: number = 0; i < value.length; i++) {
if(value[i].Id != undefined){
this.groupIdString += "(UserGroupsId eq " + value[i].Id.toString()+")";
}
}
}
});
const restQuery = "/_api/Web/Lists/GetByTitle('Weather')/Items?$select=Title,NewsBody,UserGroupsId&$filter=("+this.groupIdString+")";
ServiceManager.getRemoteService().getWeatherListItems(this.props.siteUrl, restQuery).then((value) => {
if (value[0]) {
//code
}
});
}
#Sivakumar Piratheeban,
You can put the second request in the callback of the first call.
public componentDidMount() {
this.groupIdString = "";
ServiceManager.getRemoteService().getCurrentUserGroups(this.props.siteUrl, "/_api/web/currentuser/groups").then((value) => {
if (value[0]) {
for (let i: number = 0; i < value.length; i++) {
if (value[i].Id != undefined) {
this.groupIdString += "(UserGroupsId eq " + value[i].Id.toString() + ")";
}
}
// Second
const restQuery = "/_api/Web/Lists/GetByTitle('Weather')/Items?$select=Title,NewsBody,UserGroupsId&$filter=(" + this.groupIdString + ")";
ServiceManager.getRemoteService().getWeatherListItems(this.props.siteUrl, restQuery).then((value) => {
if (value[0]) {
//code
}
});
//
}
});
}
BR

Angular 1.5 directive loop issue repeating the first element

referring to this plunker:
https://plnkr.co/edit/kBoDTXmm2XbxXjpDA4M9?p=preview
I am trying to create a directive that takes an array of json objects, syntax highlights them and its that syntax highlighted element in the page.
I have had mixed results with different watching methods, but what I cant figure out in this one is why the same id:1 is showing all the way down the list, why not id:1, id:2, id:2, id:3 etc.
angular.module("ngjsonview",[]).directive('ngjsoncollection',['$sce', function(){
'use strict';
return {
transclude: false
,restrict:'E'
,scope:{ d:'=',o:"=" }
,templateUrl: "./template.htm"
,controller:function($scope,$sce){
var fnPretty = function(objData){
if (typeof objData != 'string') { var strOut = JSON.stringify(objData, undefined, 2); }
strOut = strOut.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
return strOut.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) { cls = 'key';}
else { cls = 'string'; }
} else if (/true|false/.test(match)) { cls = 'boolean';}
else if (/null/.test(match)) {cls = 'null'; }
return '<span class="' + cls + '">' + match + '</span>';
});
};
$scope.html=$sce.trustAsHtml(fnPretty($scope.d));
$scope.$watchCollection('d',function(arrData){
$scope.arrHTML=[];
for (var i = 0, len = arrData.length; i < len; i++) {
$scope.arrHTML.unshift($sce.trustAsHtml(fnPretty(arrData[i])));
}
});
}
};
}]);
moving the timeout into a function helped with the specific problem I had
$scope.arrData=[];
function addIt(x) {
$timeout(function(){
$scope.arrData.push({id:x});
}, 100);
}
for(var i=0; i < 100; i++){
addIt(i)
}

I cant break my foreach with ajax inside

I have this:
var addresses_tmp = addresses.slice();
var final_addresses = [];
addresses.forEach(function (current_address, i) {
var near_addresses = [];
near_addresses.push(current_address);
addresses_tmp.forEach(function (next_address, j) {
if (current_address.address.info.code != next_address.address.info.code) {
var data = {
key : $scope.MicrosoftKey,
optmz : "distance",
routeAttributes : "routePath"
}
data["wp.0"] = current_address.address.location.lat + "," + current_address.address.location.lng;
data["wp.1"] = next_address.address.location.lat + "," + next_address.address.location.lng;
ajax.sendApiRequest(data, "GET", "http://dev.virtualearth.net/REST/V1/Routes/Driving", is_url=true).then(
function(response) {
var distance = response.data.resourceSets[0].resources[0].travelDistance;
if (distance < 0.020) {
near_addresses.push(next_address);
addresses_tmp.splice(j, 1);
}
if (j == addresses.length - 1) {
final_addresses.push(near_addresses);
if (near_addresses.length == 1) {
addresses_tmp.splice(j, 1);
}
addresses_tmp.splice(i, 1);
}
// if (count == addresses.length * addresses.length) {
// console.log("ya he acabado todasssss")
// }
},
function(error) {
console.log("error", error);
}
)
}
})
})
And I would like to break all function when the first foreach and the second foreach are finished but I cant put if condition to do this.
As I have ajax inside the second foreach, my variables are crazy so I cant put an if condition to break it.
I need to do this because I am compare two arrays and getting distance between two points (one in the first array and second in the other array)

Object oriented OOJS

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.

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
})

Resources