how to pass data from one function to another function angularjs - javascript

I am filtering data while searching in my application. I am facing the issue to write if condition to check the function selected data and second function filter data.
I have 5 side menus in my application. If I click any one of that, I need to store that value in a variable.
I have another function, I am looping the results there.But I need to check already stored value, and the current function's response value is same or not.
$scope.toggleTab = function (id) {
$scope.categoryId = id;
}
And my another function is,
$scope.getTags = function () {
var keywords_regex = new RegExp($scope.search.split(' ').map(function (i) { return '(?=.*' + i + ')'; }).join(''), 'i');
return $scope.getData.filter(function (data) {
return !!data.match(keywords_regex);
}).map(function (data) {
return data;
});
}
In this map function I need to check the result like this,
}).map(function (data) {
if( selectedData == data.id){
return data;
}
});
How can I do this, I used $rootScope. But When it came inside loop, the result has changed..

Related

Javascript: A dictionary of functions; one function in dictionary calls another

I have a dictionary of functions which are essentially different calls to an API I am using to receive data (in promises). The way my API has structured its data, in order to get every species from each country, I must make a call to the API modifying the https request, using a keyword q which is specific to each country. I have created an function within the dictionary called sp_b_c, which means species by country. It takes an q, which is the country, where the call itself returns a promise with a promise value of all the species within that country.
I want to create another function in the dictionary which would allow me to grab all species from each country so that it all will be contained for later use.
What I have attempted to do is to create a new function called sp_b_c_all. I make a call to my country_list function in the dictionary to obtain all of the countries. I then iterate through each country and pass each country into the function sp_b_c. I have created an array sp_b_c_entire which essentially acts like a Promise.all, because all of the promises received by iterating through countries and passing each country into a call for sp_b_c results in a returned promise.
However, when making this call getData("accesses", "sp_b_c_all")],
I receive the following error:
script.js:38 Uncaught TypeError: country_li.then is not a function
at Object.accesses.sp_b_c_all (script.js:38)
at getData (script.js:68)
at initialization (script.js:194)
at script.js:365
Below is the code this is referring to:
var getData = function(set, target, q, ...manyMore) {
var pack = [];
// ~ USE rest parameters instead, grab array from ...
// set accesses
var api_token = "9d34bf3f79ae6a8b88c4f1f54ffc3e64e5f4cdcc2cc47bd1cf429e7e247d94b2";
var accesses = new Object();
var alternative = new Object();
// ~ do a promise all, might be overload for API, so limitations
if (set == "accesses") {
accesses.sp_b_c = function(q) {
return d3.json("https://apiv3.iucnredlist.org/api/v3/country/getspecies/"+ q +
"?token=9d34bf3f79ae6a8b88c4f1f54ffc3e64e5f4cdcc2cc47bd1cf429e7e247d94b2")
.then(function(d) { return d; });
}
accesses.sp_b_c_all = function() {
sp_b_c_entire = [];
console.log(accesses.sp_b_c("AE"))
var country_li = accesses.country_list;
country_li.then(function(countries) {
console.log(countries);
countries.forEach(function(country) {
sp_b_c_entire.push(accesses.sp_b_c(country));
})
})
return sp_b_c_entire;
}
accesses.country_list = function() {
return d3.json("https://apiv3.iucnredlist.org/api/v3/country/list?token="+api_token)
.then(function(d) { return d; });
}
accesses.comp_group_list = function() {
return d3.json("https://apiv3.iucnredlist.org/api/v3/comp-group/list?token="+api_token)
.then(function(d) { return d; });
}
accesses.comp_group_specific = function() {
return d3.json("https://apiv3.iucnredlist.org/api/v3/comp-group/getspecies/"+ key +"?token="+api_token)
.then(function(d) { return d; });
}
accesses.threats_regional = function() {
return d3.json("http://apiv3.iucnredlist.org/api/v3/threats/species/name/Ursus%20maritimus/region/europe?token="+api_token)
.then(function(d) { return d; });
}
accesses.threats_global = function() {
return d3.json("http://apiv3.iucnredlist.org/api/v3/threats/species/name/Loxodonta%20africana?token="+api_token)
.then(function(d) { return d; });
}
return accesses[target]();
}
// alternative threat dataset
else if (set == "csv") {
var data = d3.csv(target + ".csv");
var transformation = data.then(
function(d) {
var container = d.map(function(d) {
return {s_n: d.ScientificName,
c_n: d.CommonName,
state: d.States,
group: d.group};
});
pack.push(container);
} // end of anon/callback function
); // end of then function
return data;
} // end of else if conditional
};
I had thought if I made the call accesses.country_list from within accesses.sp_b_c_all that I would receive the promise for the country list. I then utilize then() to access the promise value. Inside of then(countries), countries is the dataset (the list of countries. This is where I utilize a forEach loop to iterate through each country in countries, and then I pass each country into the api call for accesses.sp_b_cwith the country parameter. From this, I hope to receive a promise, and then store it in the array.
What am I doing wrong and how might I fix this? How should I alter my though process, perhaps?
If country_li is a function that returns a promise, you need to call it first to get that promise:
country_li().then(function(countries) {...})

Protractor - Issue in using one function value from another function

Hi I am new to protractor, I have below two functions, the first function is returning a promise, which I want to use in 2nd function to retrieve value from it and use it.
getColumnNumber(columnName) {
this.eh.waitForElement(this.GridsEleMap.get("HeaderTableHeaderRow"));
var colEle = this.GridsEleMap.get("HeaderTableHeaderRow").all(by.xpath(".//td//div[contains(#class,'text-content')]"));
return colEle.getText().then(function (text) {
var actIndex = text.indexOf(columnName) + 1;
logger.info("Column Index:" + actIndex);
});
}
clickRowElementUsingRowTextAndColumnName(rowText, columnName) {
var ele = this.GridsEleMap.get("BodyTable");
return this.getColumnNumber(columnName).then(function (result) {
logger.info("Text:" + result);
var cellEle = ele.all(by.xpath(".//tr//td[" + result + "]//div[#class='virtualLink']"));
logger.info("Result:" + cellEle);
return cellEle.filter(function (elem) {
browser.actions().mouseMove(elem).perform();
browser.sleep(50);
return elem.getText().then(function (text) {
return text.trim() === rowText.trim();
});
}).each(function (element) {
browser.actions().mouseMove(element).perform();
element.click();
browser.sleep(10*1000);
});
});
Whenever I am trying to use "result" object of then function applied on first function in clickRowElementUsingRowTextAndColumnName, its value is coming as undefined. Please help me with it.
I have to pass this result value to form a xpath of particular column index and perform operation on it.
You should return properly the value from the first function.
You can try the following code for example:
getColumnNumber(columnName) {
...
return colEle.getText().then(function (text) {
return text.indexOf(columnName) + 1;
});
}
If you see, it returns the actIndex.
Pay also attention that you have few code not chained properly, all protractor methods return promises which need to be chained in order to be sure to keep the flow sync.
Then, just as suggestion, try to avoid the use of xpath locators.
They are unreadable and they bring to a decrease of performances.

How to filter `objects` by it's value

In my angular controller, I would like to filter and assign some object with true value. i am trying to iterate using angular.forEach but i am getting all object as result instead of getting the truthy object.
here is my code :
$scope.splash.$promise.then(function (result) {
$scope.allApps = result; //50 apps.
// splashAppsHandler();
$scope.splashApps = angular.forEach( $scope.allApps, function (app) {
return app.projects.project.splash === true; //only 5 apps
});
console.log($scope.splashApps); //getting all 50 apps!?
});
What is the correct way to do it?
You need to store truthy objects with in an array or object. Currently you are not doing inside angular forEach.
$scope.truthyObjects = [];
$scope.splash.$promise.then(function (result) {
$scope.allApps = result; //50 apps.
// splashAppsHandler();
$scope.splashApps = angular.forEach( $scope.allApps, function (app) {
if(app.projects.project.splash === true) {
$scope.truthyObjects.push(app); // save truthy object
}
});
console.log($scope.splashApps); //getting all 50 apps!?
});

Knockout.js: computed observable not updating as expected

Edit: Added code for function populateDropdown and function isSystemCorrect (see bottom)
Edit 2 I have narrowed it down a bit and the problem seems to arise in the arrayFilter function in the computed observable. This returns an empty array, no matter what I try. I have checked that self.testsuites() looks ok right before filtering, but the filtering still fails.
I have a problem with my computed observable, filteredTestsuites.
As you can see from the screendump, the testsuites observable is populated correctly, but the computed observable remains empty. I have also tried choosing another option than "Payment" from the dropdown menu, to see if this will trigger the observable, it did not.
I would think the computed observable would be updated every time self.testsuites() or self.dropdownSelected() was changed, but it doesnt seem to trigger on neither of them.
What am I doing wrong here?
I simply want to make the computed observable filter the testsuites after the chosen dropdown option, every time either of them change.
function ViewModel() {
var self = this;
// The item currently selected from a dropdown menu
self.dropdownSelected = ko.observable("Payment");
// This will contain all testsuites from all dropdown options
self.testsuites = ko.mapping.fromJS('');
// This will contain only testsuites from the chosen dropdown option
self.filteredTestsuites = ko.computed(function () {
return ko.utils.arrayFilter(self.testsuites(), function (testsuite) {
return (isSystemCorrect(testsuite.System(), self.dropdownSelected()));
});
}, self);
// Function for populating the testsuites observableArray
self.cacheTestsuites = function (data) {
self.testsuites(ko.mapping.fromJS(data));
};
self.populateDropdown = function(testsuiteArray) {
for (var i = 0, len = testsuiteArray().length; i < len; ++i) {
var firstNodeInSystem = testsuiteArray()[i].System().split("/")[0];
var allreadyExists = ko.utils.arrayFirst(self.dropdownOptions(), function(option) {
return (option.Name === firstNodeInSystem);
});
if (!allreadyExists) {
self.dropdownOptions.push({ Name: firstNodeInSystem });
}
}
};
}
$(document).ready(function () {
$.getJSON("/api/TestSuites", function (data) {
vm.cacheTestsuites(data);
vm.populateDropdown(vm.testsuites());
ko.applyBindings(vm);
});
}
Function isSystemCorrect:
function isSystemCorrect(system, partialSystem) {
// Check if partialSystem is contained within system. Must be at beginning of system and go
// on to the end or until a "/" character.
return ((system.indexOf(partialSystem) == 0) && (((system[partialSystem.length] == "/")) || (system[partialSystem.length] == null)));
}
As suggested in a comment - rewrite the cacheTestsuites method:
self.testsuites = ko.observableArray();
self.filteredTestsuites = ko.computed(function () {
return ko.utils.arrayFilter(self.testsuites(), function (testsuite) {
return (isSystemCorrect(testsuite.System(), self.dropdownSelected()));
});
});
self.cacheTestsuites = function (data) {
var a = ko.mapping.fromJS(data);
self.testsuites(a());
};
The only thing different here is the unwrapping of the observableArray from the mapping function.

Knockout custom computed looses validation rules

I've created a custom function as seen below. It works perfekt while storing data and updating the observable MetaData values etc, but it breaks when it comes to validation.
I am using Knockout validation and have been debugging for a few hours and what I THINK i found out is the fact that the validation is run twice and the second time, all the rules of my observable has dropped, so every time the observable is valid, since there are no rules. The later code is copied from the source code here: https://github.com/Knockout-Contrib/Knockout-Validation/blob/master/Dist/knockout.validation.js
Why are my custom function making the observable dropping the validation rules?
My custom function
ko.observable.fn.valueByKey = function (key) {
return ko.computed({
read: function () {
var md = ko.utils.arrayFirst(ko.unwrap(this), function (item) {
return item.Key() == key;
});
if (md === null) {
md = new MetaData({ Key: key });
this.push(md);
}
return md.Value();
},
write: function (value) {
var md = ko.utils.arrayFirst(ko.unwrap(this), function (item) {
return item.Key() == key;
});
md.Value(value);
}
}, this);
};
Code that runs twice
var h_obsValidationTrigger = ko.computed(function () {
var obs = observable(),
ruleContexts = observable.rules();
console.log(ruleContexts);
exports.validateObservable(observable);
return true;
});
Another important part of knockout validation js
addRule: function (observable, rule) {
observable.extend({ validatable: true });
//push a Rule Context to the observables local array of Rule Contexts
observable.rules.push(rule);
return observable;
},
UPDATE 1:
I've come up with a simple solution that almost seems to work.
ko.observable.fn.valueByKey = function (key) {
var md = ko.utils.arrayFirst(ko.unwrap(this), function (item) {
return item.Key() == key;
});
if (md === null) {
md = new MetaData({ Key: key });
this.push(md);
}
return md.Value;
}
When using this, I get validation message on the element, but error-count does not rise on my view model, so the viewmodel it self is still valid, even though i get validation error.

Categories

Resources