I am working on a project in Angular 1.7.2 that utilizes some components that were built in Angular 5/6. We are downgrading the components using the downgradeComponent tool and everything is working just fine.
We recently added a new component that we need to integrate with but we need to access the components properties as well. I was looking into the ngRef directive but that does not seem to be working and I'm unable to find any other ngRef examples outside of the Angular documentation. When I add the ngRef and bind it to a variable in the current scope, it never gets assigned. Any help would be appreciated!
Angular 5 component
export class ImportedComponent implements OnInit {
variable1: boolean = true;
variable2: boolean = false;
constructor(private certService: ImportedComponent) { }
ngOnInit() {
this.variable1 = true;
this.variable2 = false
}
}
Html - w/ AngularJS 1.7.2
<imported ng-ref="importedProperty" ></imported>
<custom-button ng-if="importedProperty.variable1" [disabled]="!importedProperty.variable2"></custom-button>
Downgrading
angular
.module("blah", [])
.directive(
"imported",
downgradeComponent({ component: ImportedComponent }) as angular.IDirectiveFactory
);
The downgrading for the imported component is working because the HTML is showing up and I'm able to see the console.log()s occurring from their end but when I try to access importedProperty, I get undefined (or empty object if I initialize it as such in my scope prior)
I ended up working with the component owner who is now passing the data back as an event. I then listen for that event and use those properties accordingly
I am trying to code a cross-platform app using cordova and firebase while using the Phonegap-Cookies-Plugin to clear my cookies from my InAppBrowser but when I am using the given example :
window.cookies.clear(function() {
console.log('Cookies cleared!');
});
My console is saying : Cannot read property 'clear' of undefined.
I wanted to know if you had any ideas ?
Details : I already reinstalled the platforms and plugins to be sure it's well installed. As you will see in my extract, I am also using AngularJS, Ionic and Ui Router.
Ref : https://github.com/bez4pieci/Phonegap-Cookies-Plugin
https://github.com/apache/cordova-plugin-inappbrowser
Extract from my code :
angular.module('starter')
.controller('ProfileCtrl', function($rootScope,$scope,$state, UserSrv, $ionicViewSwitcher, $ionicModal)
{
$scope.deconnectFB = function(){
$rootScope.loggedInUser='false';
window.cookies.clear(function() {
console.log('Cookies cleared!');
});
$rootScope.ref.unauth();
$state.go("welcome");
};
I have the following code...
<div ng-controller="CalendarCtrl">
<input type="text" ng-model="model.selectedDate" ng-change="onCalendarChange()" id="calendar" />
</div>
<script>
var app = angular.module("myApp", []);
app.controller("CalendarCtrl", function($scope) {
var currentDate = new Date();
$scope.model = { selectedDate: (currentDate.getMonth() + 1) + "/" + currentDate.getDay() + "/" + currentDate.getFullYear() };
console.log($scope.model);
$scope.onCalendarChange = function() {
console.log(currentDate);
};
});
$(document).ready(function() {
$("#calendar").datepicker();
});
</script>
This code appears to work beautifully. The change event is being called and the new selectedDate is displayed correctly.
Yet I keep seeing posts where developers are using all kinds of hoops (mainly directives) to get the datepicker to work in Angular.
Am I missing something here?
Using JQuery like this means that you are not declaratively expressing what your app does in the HTML which is kind of the point of Angular.
From the angular homepage:
AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop.
Your also going to run into a lot of trouble down the road with code like
$(document).ready(function() { $("#calendar").datepicker(); });
As Angular has no idea when this has finished or what has changed. If you start using stuff like this you will need a strong understanding of how dirty checking and the digest cycle work in Angular.
Your date picker won't play nice with other directives either. For example if you put this in an ng-if and hide and show it then the date picker will not be there anymore.
Have you looked into libraries like Angular UI Bootstrap or Angular Strap. They both provide date pickers that work out of the box with Angular.
I am developing a mobile application using Cordova and AngularJS. How do I restrict bootstrapping of AngluarJS before Cordova device ready. Basically I don't want to use any of AngularJS controllers before device ready.
Manually bootstrap your Angular app:
Remove your ng-app attribute from your HTML code, so Angular doesn't start itself.
Add something like this to you JavaScript code:
document.addEventListener("deviceready", function() {
// retrieve the DOM element that had the ng-app attribute
var domElement = document.getElementById(...) / document.querySelector(...);
angular.bootstrap(domElement, ["angularAppName"]);
}, false);
Angular documentation for bootstrapping apps.
I'm using the following solution, which allows AngularJS to be bootstrapped when running with Cordova as well as when running directly in a browser, which is where much of my development takes place. You have to remove the ng-app directive from your main index.html page since that's what the manual bootstrapping is replacing.
UPDATE: I've since switched to the following method, which I think is cleaner. It works for Ionic as well as vanilla Cordova/PhoneGap. It should be the last bit of JavaScript to run - perhaps inside a script tag before the /body tag.
angular.element(document).ready(function () {
if (window.cordova) {
console.log("Running in Cordova, will bootstrap AngularJS once 'deviceready' event fires.");
document.addEventListener('deviceready', function () {
console.log("Deviceready event has fired, bootstrapping AngularJS.");
angular.bootstrap(document.body, ['app']);
}, false);
} else {
console.log("Running in browser, bootstrapping AngularJS now.");
angular.bootstrap(document.body, ['app']);
}
});
Here's the older solution I used:
// This is a function that bootstraps AngularJS, which is called from later code
function bootstrapAngular() {
console.log("Bootstrapping AngularJS");
// This assumes your app is named "app" and is on the body tag: <body ng-app="app">
// Change the selector from "body" to whatever you need
var domElement = document.querySelector('body');
// Change the application name from "app" if needed
angular.bootstrap(domElement, ['app']);
}
// This is my preferred Cordova detection method, as it doesn't require updating.
if (document.URL.indexOf( 'http://' ) === -1
&& document.URL.indexOf( 'https://' ) === -1) {
console.log("URL: Running in Cordova/PhoneGap");
document.addEventListener("deviceready", bootstrapAngular, false);
} else {
console.log("URL: Running in browser");
bootstrapAngular();
}
If you run into problems with the http/https detection method, due to, perhaps, loading a Cordova app into the phone from the web, you could use the following method instead:
function bootstrapAngular() {
console.log("Bootstrapping AngularJS");
// This assumes your app is named "app" and is on the body tag: <body ng-app="app">
// Change the selector from "body" to whatever you need
var domElement = document.querySelector('body');
// Change the application name from "app" if needed
angular.bootstrap(domElement, ['app']);
}
// This method of user agent detection also works, though it means you might have to maintain this UA list
if (navigator.userAgent.match(/(iOS|iPhone|iPod|iPad|Android|BlackBerry)/)) {
console.log("UA: Running in Cordova/PhoneGap");
document.addEventListener("deviceready", bootstrapAngular, false);
} else {
console.log("UA: Running in browser");
bootstrapAngular();
}
Note that you still need the same bootstrapAngular function from the first example.
Why manually bootstrap AngularJS with Cordova/PhoneGap/Ionic?
Some people getting here might not know why you would want to do this in the first place. The issue is that you could have AngularJS code that relies on Cordova/PhoneGap/Ionic plugins, and those plugins won't be ready until after AngularJS has started because Cordova takes longer to get up and running on a device than the plain old Javascript code for AngularJS does.
So in those cases we have to wait until Cordova/PhoneGap/Ionic is ready before starting up (bootstrapping) AngularJS so that Angular will have everything it needs to run.
For example, say you are using the NG-Persist Angular module, which makes use of local storage for saving data on a browser, iOS Keychain plugin when running on iOS, and the cordova-plugin-file when running on Android. If your Angular app tries to load/save something right off the bat, NG-Persist's check on window.device.platform (from the device plugin) will fail because the mobile code hasn't completed startup yet, and you'll get nothing but a white page instead of your pretty app.
If you are using Ionic, this solution works for browsers and devices. Credit to romgar on this thread.
window.ionic.Platform.ready(function() {
angular.bootstrap(document, ['<your_main_app']);
});
Still need to remove ng-app from your DOM element.
This solution became more robust when I used:
angular.element(document).ready(function () {
var domElement = document.getElementById('appElement');
angular.bootstrap(domElement, ["angularAppName"]);
});
UPDATE
My suggestion was to put the above within the appropriate deviceready function, e.g.:
document.addEventListener("deviceready", function() {
angular.element(document).ready(function () {
var domElement = document.getElementById('appElement');
angular.bootstrap(domElement, ["angularAppName"]);
});
}, false);
On using the solution from TheHippo:
document.addEventListener("deviceready", function() {
// retrieve the DOM element that had the ng-app attribute
var domElement = document.getElementById(...) / document.querySelector(...);
angular.bootstrap(domElement, ["angularAppName"]);
}, false);
It doesn't work in the browser because "cordova.js" gets resolved by the Cordova or Phonegap building process and is not available in your localhost or emulated testing environment.
Thus the "deviceready" event is never fired. You can simply fire it manually in your browsers console.
var customDeviceReadyEvent = new Event('deviceready');
document.dispatchEvent(customDeviceReadyEvent);
Also make sure, that the bootstrap of angular gets triggered after setting all of you angular modules/controllers/factories/directives etc.
In most cases you probably don't need to block loading your angular app until after deviceready (mind that it can take several seconds for deviceready to fire if you have a lot of plugins).
Instead you can use something like this lib (https://github.com/arnesson/angular-cordova) which solves the deviceready issues for you by automatically buffering calls and then execute them after deviceready has been fired.
Anybody know if the angularJS animations work with requireJS? ng-animate isn't recognized when I use requireJS modules. If anyone know how to get it working can you explain what the best approach is? I should add that I am indeed using the angularJS version 1.1.4
AngularJS is MVW framework and requireJS is AMD loader. So the problem is in your module complatibility or setup or something else and not in requireJS.
I just grabbed this from one of my abandoned angular apps - but seems to work just firing it up now.
Hope it helps. Oh I should mention this is javascript based animation using jquery (fadeIn and fadeout).
var myApp = angular.module('apps', ['ngSanitize']);
myApp.animation('animate-enter', function () {
return {
setup: function (element) {
var viewId = element.parent().attr('id');
$("#" + viewId).hide();
},
start: function (element) {
var viewId = element.parent().attr('id');
$("#" + viewId).fadeIn(500, function () {
});
}
}
});