AngularJS Directive and Isolate Scope - service

I am trying to understand how to pass data through my directive so that I can bind it at the view level. I believe I understand the separation of controller scope vs. the directive isolate scope but I cant seem to get a simple json result out to my view. My JSFiddle can be found here http://jsfiddle.net/jamesamuir/2KLVj/4/.
app.directive('testList', function (testService) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
$scope.name = 'isolate scope';
$scope.data = {};
$scope.data.loadtext = testService.getJSON().then(function (data) {
alert(data);
element.addClass("red");
});
}
}
});
It seems to me that this should work but, alas, it does not. Any help would be greatly appreciated.

Inside your then() callback, assign data to data.loadtext:
testService.getJSON().then(function (data) {
alert(data);
element.addClass("red");
scope.data.loadtext = data;
});
fiddle

Related

How to select a drop down using protractor?

Can any one help me on how to select a drop down in protractor.
Page Object code
function selectDropdownbyNum(element, optionNum) {
if (optionNum) {
element.all(by.tagName('option')).then(function(options) {
browser.sleep('5000');
options[optionNum].click();
console.log('Desired value selected');
});
}
}
var pageName= function(){
this.selectTier = async function(){
var Tiers = element(by.xpath(/*element value*/));
console.log('select silver method');
browser.sleep(5000);
selectDropdownbyNum(Tiers,2);
console.log('value selected');
};
};
module.exports = new pageName();
And Spec is as follows
it('select Silver Tier',async function(){
browser.ignoreSynchronization = true;
console.log('Executing silver tier selection test case');
await pageName.selectTier()
});
I have tried the above code. I am able to print all the values of the drop down, but am unable to click.
Is their any mistake in the above code.I can print the 'Desired value selected'. But value was not selected
May this will help you for selecting option
element(by.cssContainingText('option','Option value')).click();
or
element(by.id('id')).sendKeys("Values from option");
this worked for me
Try:
var Tiers = element(by.xpath(dropDownValue));
Tiers.click();
selectDropdownbyNum(element, optionNum) {
if (optionNum) {
element.all(by.tagName('option')).then(function(options) {
options[optionNum].click();
});
}
}
selectDropdownbyNum(Tiers,4)
Note:
avoid using Xpath example use :
element(by.css('select[formcontrolname="any value according to situation"]'));
I haven't tested it, but I suppose it's because of the nested promise you are using inside the for loop. The nature of the promise is to be async, and the for loop is synchronous, which results in the loop complete whyle the very first promise items[i].getText().then get's resolved and that's why your click didn't succeed. If you don't need to know the option names, then just remove the nested promise items[i].getText() and just execute the click in the loop.

Protractor how to wait for options

I have code like this:
element(by.model("roleSelection.role")).element(by.cssContainingText('option', newRole)).click();//.then(function() {console.log('role click')})//;
where the options is loaded via a call to the server.
I can wait for the first element by doing this
browser.wait(function() {
return browser.isElementPresent(by.model("roleSelection.role")).then(function(present){
return present;
});}, 8000);
and it seems to work. But how can I wait until the "sub-element" is clickable.
I have tried this
browser.wait(function() {
return browser.isElementPresent(by.model("roleSelection.role")).then(function(present){
if (present) {
var elm = element(by.model("roleSelection.role"));
return elm.isElementPresent(by.cssContainingText('option', newRole)).then(function(subpresent) {
return subpresent;
});
}
}); }, 8000);
Have you tried clickable? Something along these lines
var EC = protractor.ExpectedConditions;
var select = element(by.model("roleSelection.role"))
var isClickable = EC.elementToBeClickable(select);
browser.wait(isClickable,5000); //now options should have been loaded by now
Well, try to this: https://angular.github.io/protractor/#/api?view=ExpectedConditions.prototype.elementToBeClickable
But, Please keep in mind, Protractor is suitable for angular webpages and interactions, and animations. For example ng-animate. So, it is not sure to working for example jquery, or other animates.
In this way:
onPrepare: function () {
// disable animations when testing to speed things up
var disableNgAnimate = function () {
angular.module('disableNgAnimate', []).run(function ($animate) {
$animate.enabled(false);
});
};
browser.addMockModule('disableNgAnimate', disableNgAnimate);
}
Or you can switch in script way in browser.executeScript().
Please see this link. It works only jquery animations.
If you not have animate problems. Use setTimeout() JS function.

appAPI.tabs.getActive returning empty object in firefox

appAPI.tabs.getActive returning empty object in firefox
appAPI.ready(function()
{
// retrieves the information for the active tab
appAPI.tabs.getActive(function(tabInfo) {
console.log(
'tabId: ' + tabInfo.tabId +
' tabUrl: ' + tabInfo.tabUrl
);
});
});
I tried above function/code appAPI.tabs.getActive in my extension, its working properly in Chrome but its not working in firefox, its giving me empty object {}. If somebody know whats the issue is please reply on this asap, thanks in advance
From experience, this only occurs when using appAPI.tabs API in a scope other than the background scope.
Please note that it is only supported in the background scope.
To use appAPI.tabs.getActive in other scopes, from the scope send a message to the background scope to obtain the tabInfo object, and then send the data back to the original scope, something like the following example in the popup scope:
popup.html:
function crossriderMain($) {
var tabInfo = null;
appAPI.message.addListener(function(msg) {
if (msg.type==='set-tabInfo') {
tabInfo = msg.tabInfo;
}
});
appAPI.message.toBackground({type:'get-tabInfo'});
}
background.js:
appAPI.ready(function() {
appAPI.message.addListener(function(msg) {
if (msg.type==='get-tabInfo') {
appAPI.tabs.getActive(function(tabInfo) {
appAPI.message.toPopup({type:'set-tabInfo', tabInfo:tabInfo});
});
}
});
});

How to add validation attributes in an angularjs directive

I am trying to write an angular directive that adds validation attributes to the tag, but it doesn't seem to be working. Here is my demo. You will notice that "Is Valid" remains true if you delete the text in the second input box, but goes to false if you delete the text in the first input box.
http://plnkr.co/edit/Rr81dGOd2Zvio1cLYW8D?p=preview
Here is my directive:
angular.module('demo', [])
.directive('metaValidate', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.attr("required", true);
}
};
});
I'm guessing I am just missing something simple.
All rules for validation of the form are being read in compilation phase of the form, so after making changes in a child node, you need to recompile form directive (form it's a custom directive in AngularJS). But do it only once, avoid infinite loops (your directive's 'link' function will be called again after form's compilation).
angular.module('demo', [])
.directive('metaValidate', function ($compile) {
return {
restrict: 'A',
link: function (scope,element, attrs) {
if (!element.attr('required')){
element.attr("required", true);
$compile(element[0].form)(scope);
}
}
};
});
Working plunker: http://plnkr.co/edit/AB6extu46W4gFIHk0hIl?p=preview
Be careful of infinite loops and recompiles, a better solution is here: Add directives from directive in AngularJS
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
terminal: true, //this setting is important to stop loop
priority: 1000, //this setting is important to make sure it executes before other directives
compile: function compile(element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
return {
pre: function preLink(scope, iElement, iAttrs, controller) { },
post: function postLink(scope, iElement, iAttrs, controller) {
$compile(iElement)(scope);
}
};
}
};
});
Working plunker is available at: http://plnkr.co/edit/Q13bUt?p=preview
I know this is quite an old question, but for what it's worth, the angular docs describe ng-required which takes a boolean value. This solved a similar problem I was having.
http://docs.angularjs.org/api/ng/directive/input

jQuery get object moused over

I have this code:
$('*').mouseover(function() {
$('#log').text($('*').id);
});
When you mouse over any element on the page, I want #log to have the id of that element. Obviously the code above doesn't work... How do I do this?
$('*').mouseover(function() {
console.log($(this).attr('id'))
});
In almost all jQuery callbacks, "this" is the object on which the callback is being executed.
$('*').mouseover(function() {
$('#log').text($(this).attr('id'));
});
You can also use event.target
var $log = $("#log");
$('*').mouseover(function(event) {
$log.text($(event.target).attr('id'));
event.stopPropagation();
});