Angular 1.5.7 Controller Scope Failing in iOS 9.3+ - ios

I've been struggling a bit to successful get the following Angular 1.5.7 app to properly display user data injected into the Scope of my Controller. It works great on all browsers within a Windows Desktop environment but fails to display the data (it merely displays the template bindings) in iOS 9.3.5.
The Router:
routingApp
.config(function ($routeProvider) {
$routeProvider
.when('/user', {
controller: 'userController',
templateUrl: 'app/partials/userPartial.html'
})
.when('/contacts', {
controller: 'contactController',
templateUrl: 'app/partials/contactPartial.html'
})
.otherwise('/');
});
The Controller:
routingApp
.controller('userController', function ($scope, User) {
//Specify accessible controller attributes
$scope.User = new User();
});
The Partial:
<div class="user" id="userWrapper">
<h1 class="header">Contact Information</h1>
<span class="userField">Name: {{User.name}}</span>
<span class="userField">Phone: {{User.phone}}</span>
<span class="userField">Email: {{User.email}}</span>
<h1 class="header">Address Information</h1>
<span class="userField">Street: {{User.address.street}}</span>
<span class="userField">Suite: {{User.address.suite}}</span>
<span class="userField">City: {{User.address.city}}</span>
<span class="userField">Zipcode: {{User.address.zipcode}}</span>
</div>
See the example here: http://changelib.com/routing/
Full code is here: https://github.com/Thoughtscript/demo-angular_routing
Comments: I've heard that ng-App requires some additional configuration for iOS. Not sure if that's true but I've tried a number of things including directly bootstrapping the application (not sure if I did this correctly), switching to another router library (am using angular-route.min.js), and a couple smaller changes that didn't improve the situation. Any help is much appreciated! Thanks!

Was an idiot - some unsupported ES6 code and uncommitted changes to router dependencies fixed the issue. To be clear, the code above was fine (the problem lay in the factory and service). One take away, double-check ES6 support in iOS.

Related

How to create a link to external URL in Angular 2

I am new to Angular. I am starting with ver. 2.
I need to link to a file://... URL.
I tried normal href:
Note: app is a model object of the web which deals with applications.
<a target="_blank" href="file://{{app.outputPath}}/index.html">no link here</a>.
That doesn't work - the link is there, with correct URL, but Angular seems to block the event somehow. Why?
So I've seen ng-href but that's for Angular 1.x. And there's no *ngHref from what I can tell. So this was just a naive try:
<a target="_blank" *ngHref="file://{{app.outputPath}}/index.html">over a directive</a>.
Also I have seen something with routing but that appears to be intended only for internal links within the application:
<a [router-link]="['/staticReport', {path: app.outputPath}]">see the report</a>.
app.component.ts:
#RouteConfig([
...
{path:"/staticReport/:path", redirectTo: 'file:// ???? ' }
])
What's the way to create an external link?
I assume app is assigned async. You can work around this using the Elvis operator:
<a target="_blank" href="file://{{app?.outputPath}}/index.html">no link here</a>.
to not break the binding when Angular tries to resolve it before app actually has a value.
Original
This worked for example:
#Component({
selector: 'my-app',
template: `
<h2>Hello {{name}}</h2>
<a target="_blank" [href]="'file://' + outputPath + '/index.html'">no link here</a>
`
})
export class App {
outputPath:string = 'www.google.com';
constructor() {
this.name = 'Angular2';
}
}
Plunker
Actually, your first example works fine as well
<a target="_blank" href="file://{{outputPath}}/index.html">no link here</a>
Plunker

Binding lost (after click) in angular js small example

I have a very small application in Angular JS. It's placed inside a bigger rails application, but I don't see too much interaction. The angular application, allows the user to interact with a group of categories. As easy as:
var angular_app = angular.module('angular_app', []);
angular_app.config(['$httpProvider', function($httpProvider, $cookieStore) {
//Protection
}]);
angular_app.controller('CategoriesController', function ($scope, $http) {
$scope.isEditing = false;
$scope.categoryName = '';
$http.get('/api/categories').success(function(data) {
//We use this to data-bind with the HTML placed below
$scope.categories = data;
});
$scope.addNewCategory = function() {
...
}
$scope.editCategory = function(index) {
if (!index)
return;
var selectedCategory = $scope.categories[index];
// With ng-show, we make visible the part of the UI
// that should be used for editing
$scope.isEditing = true;
}
$scope.cancelEditCategory = function() {
$scope.isEditing = false;
}
$scope.deleteCategory = function(index) {
...
}
});
angular.element(document).ready(function() {
angular.bootstrap(document, ['angular_app']);
});
The idea is that the information is shown in a list, and we have an 'edit' button that allows the user to see other part of the UI that will let him perform changes.
<div ng-controller="CategoriesController">
<div ng-show='isEditing' class="popup_menu">
DIV FOR EDITING
</div>
<ul>
<li ng-repeat="category in categories">
<a href="#" ng-click='deleteCategory($index)'>[X]</a>
<a href="#" ng-click='editCategory($index)'>[E]</a>{{ category.name }}
</li>
</ul>
<input type="text" id="categoryTextBox" ng-model="categoryName"/>
<button id="submit" ng-click='addNewCategory()'>New category</button>
</div>
When I'm clicking the edit button, the corresponding part of the UI gets visible, but just after that, something happens, and the ul that should render the list, looses completely the binding, just showing something like:
[X] [E]{{ category.name }}
When it must be showing:
[X] [E]computer science
[X] [E]politics
[X] [E]news
(Which is what I have in the scope). It happens a few after the click (and works for a sec). No errors on the console, no interactions with other libraries (as far as I can see).
Thanks!
Turbolinks
I have no experience with Angular, but perhaps your problem could be to do with Turbolinks - this is a way of Rails loading the <body> tag of a page only - keeping the <head> intact.
Turbolinks is notorious for Javascript on Rails, as each time you reload your <body> without reloading the <head> part of your page, all your JS bindings are going to disappear. The solution to this, in normal JS, is to use JQuery / Javascript delegation, and delegate from the document object:
$(document).on("action", "delegated_object", function(){
...
});
Apologies if this does not work - it's a common issue for us, but as I have no experience with Angular, I don't know if it's going to help you or not.
It seems that I should have been more careful with the links:
<a href="#" ng-click='deleteCategory($index)'>[X]</a>
<a href="#" ng-click='editCategory($index)'>[E]</a>{{ category.name }}
Don't know exactly how this works, but seems that if the link has his href attribute, a GET request is made against 127.0.0.1, breaking in some way the angular code. If you put them like:
<a ng-click='deleteCategory($index)'>[X]</a>
<a ng-click='editCategory($index)'>[E]</a>{{ category.name }}
The problem will be solved. Thanks all for reading and helping!

open external link in angulardart in new tab/window

I am writing an angular dart app and the app contains a few links that point to other resources on the server.
I have a weird experience that some links are "handled" by angular and some not.
For example in the code I have these two links that are close to each other. Both are inside the same controllers scope. The first link is handled by angular, the second is opened in a separate window as configured. (Maybe due to the hashbang in the url?)
...
<div class="span4">
<div class="address">Direktlink</div>
not working link
</div>
</div>
<div class="row-fluid">
<div class="span12 modal_image">
<img src="http://localhost/modules/mod_orchit_baumodul/ajax/composite.php?haus=Aachen&variante=8&pos=0" class="ng-binding">
</div>
</div>
</div>
So I created a small directive
/**
* https://github.com/angular/angular.dart/issues/335
* https://github.com/angular/angular.dart/issues/864
*/
#NgDirective(
selector: 'a[externalLink]'
)
class ExternalLinkDirective {
Element element;
ExternalLinkDirective(this.element) {
element.onClick.listen((Event event){
window.location.assign(element.attributes["href"]);
});
}
}
but this has the disadvantage that I can't open the link in a new tab or window.
I couldn't find something that helped me with that in the API docs. :-(
Is there a way to open the first link in a new tab too?
OK, I figured it out. But it opened a new window each time, so I check for the target first.
Feel free to use this directive yourself.
/**
* https://github.com/angular/angular.dart/issues/335
* https://github.com/angular/angular.dart/issues/864
*/
#NgDirective(selector: 'a[externalLink]')
class ExternalLinkDirective {
Element element;
ExternalLinkDirective(this.element) {
element.onClick.listen((Event event) {
String target = "_SELF";
if (isValidTarget()){
window.open(element.attributes["href"], element.attributes['target']);
}
else window.location.assign(element.attributes["href"]);
});
}
bool isValidTarget(){
return element.attributes.containsKey("target") && element.attributes['target'].toLowerCase()!='_self';
}
}
Since route_hierarchical-0.4.19 this issue seems to be fixed.

how can i use google earth API with backbone.js+jquery mobile?

How can i use google earth API with backbone.js+jquery mobile ?
I have created application using backbone.js, underscore.js and jQuery Mobile.
For google earth API, I am using sample code listed at https://developers.google.com/earth/documentation/#using_the_google_earth_api
My template rendering, and all other pages are working fine But when i load google earth API in one tag, it's not loading and in js console i get message: "ERR_INVALID_DIV ".
Google.earth module never calls back initCallback, It's always calls failureCallback when google.earth.createInstance is invoked.
I explain some sample code of mine application as under, so based on that may be you get my code structure and it helps you to solve my issue.
my js code as under,
myjs1.js
var ge;
function init() {
google.earth.createInstance('map3d', initCB, failureCB);
}
function initCB(instance) {
console.log(' init call back call ');
ge = instance;
ge.getWindow().setVisibility(true);
}
function failureCB(errorCode) {
console.log(errorCode);
}
Now my Backbone code as under,
myjs2.js
WebApp.MyPage= Backbone.View.extend({
initialize:function (result) {
this.template =_.template($('#myPage').html());
},
render:function (eventName) {
var self = this;
mydata = object dict of my data;
$(self.el).html(self.template({mydata:mydata}));
google.load("earth", "1");
init();
google.setOnLoadCallback(init);
}
Now my HTML code like as under,
<script type="text/template" id="myPage">
<div data-role="page">
<div data-role="content">
<div id="map3d" style="height: 400px; width: 600px;"></div>
</div>
</div>
</script>
myhtml.html
Is there any way to fix this?
Any help appreciated.
The Earth API works with the Google Earth Plugin, which is available only on Windows and Mac OSX. It is not available on mobile devices, sorry!
If you're testing on your Mac or Windows system, you should be able to get it working. The error code ERR_INVALID_DIV sounds like it isn't finding the map3d div. I would put a debugger; statement in the code just before the google.earth.createInstance() call, and then look around in the DOM inspector and see if map3d is in the DOM. It should be coming in from your template if that part is working.
But this won't help you when you try to load your site on a mobile device, because you won't have the Earth plugin available there.

I got jquery-ui sortable working with meteor templates, but is it a bad hack?

I'm trying to use jquery-ui sortable with nested templates in Meteor, as follows. Here are the two templates in question:
<template name="activityEditor">
{{! the main activity editor view }}
<div class="activity-editor">
<input type="text" name="title" class="input-xxlarge" value="{{info.title}}" placeholder="Type a title here...">
<div class="activity-steps">
{{#each info.steps}}
{{>activityStepEditor}}
{{/each}}
</div>
</div>
</template>
<template name="activityStepEditor">
{{! the container view for each step editor }}
<div class="activity-step" data-id="{{_id}}">
<div class="order">{{order}}</div>
{{!....stuff...}}
</div>
</template>
and the template code (using coffeescript):
_.extend Template.activityEditor, {
# ...stuff...
rendered: ->
$(".activity-steps").sortable {
items: '.activity-step'
handle: '.order'
update: ->
stepIds = ($(el).attr('data-id') for el in $('.activity-step'))
$('.activity-steps').empty() #this must be done in order to steps to re-render properly
Lab.Activity.reorderSteps stepIds
}
$(".activity-steps").disableSelection()
}
The only way I can get this code to work and properly rerender the order is by emptying the container of my sortable elements right after they update with $('.activity-steps').empty(). I've tried cancelling the update event and forcing a rerender by changing another variable watched in the context, but any change causes Exception from Meteor.flush(): undefined after which I can't rerender anything until page reload.
This seems to work, and everything rerenders great. So my question is: is there any reason why I shouldn't do this? Is there a better, standard practice way to handle the sortable that I'm not seeing?
In the near future there'll be a better way to do it, as Meteor team is developing its new rendering engine: http://youtube.com/watch?v=ISNEhPG0wnA
(in this video, Avital Oliver shows exactly a way to do it without redrawing the screen: the object in the list is actually moved on all clients)
See this Meteor's Github Wiki entry for more technical info:
http://github.com/meteor/meteor/wiki/New-Template-Engine-Preview
While that's not officially published, if you need it right now, you could try Nazar Leush's approach:
http://github.com/nleush/meteor-todos-sortable-animation
He also published a working example here: http://todos-dnd-animated.meteor.com

Resources