Thursday, April 14 2016 2:13 PM

Problems with window.open under iOS using Ionic/Angular and Cordova

Author: matthias - Last modified: Wednesday, August 3 2016 10:13 PM

en cordova  ios  angular  ionic  javascript  bug  gap  csp

This is just a short note about how I solved a weird problem I recently experienced when window.open wouldn't work using Ionic/Angular with Cordova under iOS (9).

It's about having trouble to get window.open actually opening a window, not within current view, nor within new in-app-browser or external browser window. And it is related to using Cordova plugins, especially inAppBrowser, and having a CSP (Content-Security-Policy) defined with the main HTML file.

Searching on e.g. stackoverflow I wasn't able to find someone describing the very same problem and it was hard to find articles that brought me on the right path. Took me some time to debug stuff. So, I'm pretty sure there must be others out there who're facing the same problem I want to describe as concise as possible:

Scenario & Objective

A controller function (available through $scope) is defined as a ng-click attributes` value as:

<a ng-click="openTerms()">Terms & Conditions</a>

The function should open a new in-app-browser window and is defined within an angular controller like this:

$scope.openTerms = function() {
   window.open('http://www.example.com/terms', '_self', 'location=yes');
}

Effect

It works as expected when tested within a Desktop browser. But nothing happens on click when deployed and tested within the iOS simulator or directly on the device, (more precisely: under iOS 9 in my case). Additional effect I experienced however is that the window unexpectedly opens when the original click is followed by another action taken like clicking on a form field or triggering an internal router navigation step.

Inspecting the Cordova/iOS device logs as well as JavaScript logs shows up entries that caught my attention to investigate on it:

cordova.js: xxxx deviceready has not fired after 5 seconds

In my case there was also another entry telling that Ionic was 'not ready' due to incomplete loading of plugins.

When having a close look on the JavaScript console I discovered log entries complaining that the Content-Security-Policy denies access to resources under the URL scheme gap://.

Solution

Adjust your Content-Security-Policy to allow accessing resources for gap::

<meta http-equiv="Content-Security-Policy" content="
    default-src
       'self' 
       gap:
       ...
    ...
">

Background & Conclusion

The gap scheme is Cordova specific, it enables JS <-> native communications for iOS. A missing CSP entry somehow prevents the plugins from loading fully or correctly.

Strange enough, using Ionic and Cordova examples extensively, there hasn't been a single example template nor note about not to forget the famous gap url scheme entry...

So, to be honest: I'm not sure about the exact root causes and it's still confusing me. But I haven't got enough time to spend more time on investigating on every single strange behavior or effect. This article just describes my specific scenario and how I successfully solved it.

If you want to dive deeper into the details of Cordova and Content-Security-Policies under iOS, you might want to check an in-depth article about it.

Hope to help others with it!

Comment / Share »
Tuesday, October 13 2015 9:07 PM

Do we need (a discussion about) jQuery?

Author: matthias - Last modified: Tuesday, October 13 2015 9:35 PM

en jquery  javascript  react  comment  opinion

Discussions about the role of jQuery bubble up these days. Paradigms change, not at least triggered by concepts (re-)introduced with React, Flux and redux. Should we try to avoid jQuery and direct DOM manipulation if possible? I'm not sure, but I want to share some thoughts I had reading a thread titled "Stop say You Don't Need jQuery" in the JS group of linked.in.

No doubt jQuery helped all of us in rapidly developing beautiful cross-browser UI features. No doubt either that it's pretty easy to write messed up code with jQuery, especially when your project is about to grow quickly... It's a question of time & budget, developer skills, performance considerations and of course your individual project needs: Every situation needs the right technologies, patterns, tools, libraries, frameworks, "sandbox areas" and ideas of how all of this can stay maintainable and subject to be refactored frequently. Always keep in mind that a growing codebase is hard to test if it's "hacked"!

If some of your project needs are perfectly covered by specific jQuery plugins – is it okay to start developing with that now? I think: Yes. If criteria stated above is fulfilled.

Think of an application/project you start developing using jQuery today. My advices:

  • Write code that people can quickly understand, that you understand when returning to it one year later.
  • Use either a well supported framework with a bright community or even write Vanilla JS, but add structure by following some architecture pattern.
  • Separate concerns, don't leave people alone with $.callback(hell) spaghetti code!
  • Let $.magic() only do the magic!

Then, maybe in 2016, there's this absolutely cool way of integrating and developing rich UI features by just using that awesome new "React Declarative Decorator Dynamite" ES2016 mixin style stuff... You'd probably like to move your code base towards it without rewriting everything, right? You don't? Ah, come on, then just write down jQuery code like it comes to your mind... ;-)

By the way: Did I mention React? Ever tried Flux or even redux?

Kidding.

Partly.

Comment / Share »
Tuesday, June 16 2015 10:59 PM

Talk: Token based authentication with JWT

Author: matthias - Last modified: Tuesday, June 16 2015 10:59 PM

en jwt  jws  json  token based authentication  javascript  hhjs  talk

I just want to share some slides I created for my talk "Token based authentication with JSON Web Tokens (JWT)" I gave yesterday, on June 15th, at Hamburgs JavaScript HH.JS meetup.

Token based authentication with JWT

What's that about? I'll try to summarize: JWT, pronounced jot, evolves to get the standardized specification and format for compact "web-safe" tokens that combine the benefits of tokens (over cookies) with the concept of "claim based" authentication information which reside self-contained as JSON representation within a signed (digest hash) and optionally encrypted token.

Feel free to correct or improve (feedback welcome!), copy, modify or share this presentation. If you're willing to use this presentation or parts of it for your own talk, you're welcome - just please let me know: I'd happy to hear about that and also appreciate if you leave a short reference to the original presentation and myself as the author.

Click here to directly get to the presentation on "Prezi"

Comment / Share »
Thursday, April 23 2015 11:17 AM

Next: JS Unconf April 25 & 26 in Hamburg

Author: matthias - Last modified: Thursday, April 23 2015 11:17 AM

en jsunconf  unconference  hamburg  hhjs

JSUnconf

Hurray, I will attend at the JS Unconf this coming weekend in Hamburg. Anyone coming over here from outside to meet and have some good conversation?

Some time in spring of 2014 I started to attend the meetups of the Hamburg JavaScript group HH.hs regularly and found out to meet some very friendly, smart and open-minded guys. HH.js founder and JSFuck mastermind Martin Kleppe is also co-organizer of the Unconference, so I'm expecting to see several of you familiar guys there as well.

Anyhow, also I'm looking forward to meet some new JS guys or even meet someone I haven't seen for quite a while, maybe there are some attendees coming over here from other cities? Rumors say there's a small village claiming to be Germanys startup and tech capitol somewhere in the east, something with "B"...? Leave a comment to this post if you like, I'll get back to you!

I'm actually a bit excited about that since this will be the first time I'm attending an unconference at all. I'm looking forward to have some nice and valuable days together with all of you. I'm pretty sure we'll have a good time with interesting talks. See you soon!

Comment / Share »
Wednesday, April 8 2015 9:17 PM

React hates me: "Overcontrolled" components

Author: matthias - Last modified: Wednesday, April 8 2015 9:54 PM

en javascript  react  flux  state  checkbox  dom  html  events  prevendefault

More accurately: The DOM hates me. I'm currently hacking a lot of React (with fun) and thought that strictly bypassing the default handlers for user input element onChange events in favor for a fully controlled value flow through React components' state and props might be a good idea. Actually, it is not.


Abstract and advice for the impatient: Don't build React "controlled components" in conjunction with preventDefault() in event handlers listening to onChange (which wraps onKeyUp/Down...) events. Silly idea.


Controlled Components

If you found your way to this post, you're potentially in some similar situation to the one I tried to summarize above: You're using React Forms with Controlled Components and for whatever reason you want to take over full control for every type of user input, typically listening to the React wrapped onChange event (good idea!) and preventing default behavior by calling preventDefault() (bad idea!) – meaning that you also have to take care of setting the state of appropriate properties which in turn update the input fields as soon as the render() method is automatically called on state value changes.

Stressing React/Flux

If you're still think this sounds like a somewhat curious approach, you're right. Anyhow, let me just give a short explanation of my motivation: I'm stressing the concept of React/Flux that way that I even want the state of user input fields to be reflected in a related store – and vice-versa. Therefore dispatched actions that update the stores' properties which values flow back through change events emitted thereafter for eventually updating the DOM sounded like a good idea to me. Yes, give me full control over every user input and create a keystroke state! Well, just an idea. Unfortunately not one of my best.

A code fragment to illustrate the situation:

var TestForm = React.createClass({

  getInitialState: function() {
    return {
      message: 'Hello!'
    };
  },

  handleValueChange: function(e) {
    e.preventDefault();
    // Here I'm calling some Flux style action (creator) which in turn
    // emits a change event and updates the components' state
    this.actions.sendMessageToTheWorldViaFluxStore(e.target.value);
    // (instead of directly reflecting the value via this.state:)
    //this.setState({ message: e.target.value });
  },

  render: function() {
    return (
      <div>
          <input 
              type="text"
              onChange={this.handleValueChange} 
              value={this.state.message} />
      </div>
    );
  }
});

Problems...

Basically this approach seems to be possible and behave like expected when using e.g. standard text input fields. You can catch the current value, store or manipulate it and finally assign the value to a state variable. But you'll face two major problems soon, both not directly related to React but to the nature of HTML elements and the DOM, namely:

Checkboxes (and Radio Buttons): Manually updating state fails for checkboxes (and without having tested it: I think for radio controls as well). Why? The problem one will face is that the checkbox onChange event behaves in a special way since the era of HTML (how could I forget!): You may not toggle the state of a checkbox manually via the .checked property. Nor does React. The onChange (onClick) event is fired after the element state changed internally. This may just be reverted based on the return value of the event handler. See this post for a comprehensive examination of this fact.

Performance: It seems to be reasonably fast to capture the user input events for immediately assigning the values back to the state variable, so that the Virtual DOM updates and eventually tiny parts of the actual DOM is re-rendered. But as soon as those values go a longer way through JavaScript objects, event listeners and further manipulation, it significantly slows down Browser performance and kills UX (noticeable lag during typing!).

... and the solution.

"But don't you see", you may say, "that you must not use preventDefault() and just go on like you want with all that Flux crap! State may be updated and reflected (delayed) either way." Yes, absolutely. Call me an idiot. Let the browser do its very basic jobs. (But... unfortunately then it cannot be guaranteed that the captured input fields actually reflect the state of my store... what about race conditions when updating... uhh... ouch! ... Well, who the f--- cares!)

Here's a React fiddle dealing with that stuff.

Comment / Share »
Saturday, March 29 2014 9:41 PM

How to manually fix a Plesk glitch where locally generated E-Mails get lost

Author: matthias - Last modified: Monday, March 31 2014 7:15 PM

en plesk  postfix  e-mail  bug  domain  mail service  mta  postman

Are you using Parallels Plesk with postfix, configured a domain for which E-Mail is handled on a foreign MX host and wonder why E-Mails created on that system (e.g. through PHP form mailer scripts) vanish and won't be transported to their destination? Yes? Then read on.

Oh dear, though Parallels Plesk greatly improved in a lot of aspects over the years, there're some bugs that seem to be "built in", like being a feature rather than a bug. But: If you start googling and searching for solutions you'll find a lot of (old) discussions, all referring to more ore less the same problem but hardly any of them giving helpful hints. I'll try to provide a straight description and solution for that specific situation and Plesk bug.

Versions affected

I faced the behavior described below years ago with older Plesk versions but today struggled with it again. My currently used and affected version is Plesk Panel 11.5.30 (at least until micro-update #35).

Situation

Let's assume you configured a domain, we name it test.com, within Plesk panel to be used for e.g. website hosting. For whatever reason on initial domain setup you've chosen to activate "E-Mail service" for that domain. But you'd configure neither E-Mail addresses nor mailboxes for that domain. You probably also don't need to configure DNS for that domain because that's done elsewhere - like the whole E-Mail (MX) stuff.

Problem

E-Mails to recipients within test.com that are generated on your Plesk host won't get transported to the correct (publicly configured MX) host. Example: E-Mails generated by a PHP form mailer script sent to info@test.com get lost. You probably register some kind of log entry in /opt/psa/var/log/maillog telling you Message aborted.

Reason...

Postfix (MTA used by Plesk) is configured with entries for test.com in the virtual_domains database. That means: Before evaluating any other way of transport, the local mail transfer agent, i.e. postfix, decides to deliver this E-Mail locally. And this is deadly wrong in our case.

... and the actual Plesk Bug

First idea is of course to uncheck "Activate E-Mail Service" in your Plesk Panels configuration page for E-Mail settings (Panel path: ... / test.com / E-Mail / E-Mail Settings). And then, your next E-Mail to info@test.com generated on that host ...fails again! Here's the specific Plesk bug: postfix virtual_domains (+ virtual) database entries are never cleaned up after "E-Mail Service" was activated once for a specific domain - even if you later deactivate this option in your Plesk domain setup configuration.

Solution

Use the shell. Find the postfix database (hash) files. Search and modify the virtual_domains as well as virtual database files using postmap. Be careful, you've been warned! But things are pretty straight forward:

$ cd /var/spool/postfix/plesk
$ postmap -s virtual_domains | grep "test.com"
test.com    test.com/
$ postmap -d test.com virtual_domains

Basically, that's it! When working with the Plesk Panel, be sure not to check "Activate E-Mail" for test.com again and you should be fine. Now, while next is not mandatory to restore desired behavior, you should also cleanup your virtual database defining user E-Mail alias addresses. Those were also automatically generated by Plesk on initial domain "Mail Service" setup. Check the entries, it will probably look something like this:

$ postmap -s virtual | grep "test.com"
postmaster@test.com    postmaster@localhost.localdomain
root@test.com    root@localhost.localdomain
mailer-daemon@test.com    mailer-daemon@localhost.localdomain
anonymous@test.com    anonymous@localhost.localdomain
drweb@test.com    drweb@localhost.localdomain

Go, take your time and delete the unwanted entries, step by step:

$ postmap -d postmaster@test.com virtual
$ postmap -d root@test.com virtual
...

Hope that was helpful for some of you guys out there. Now I'll go and submit a bug report at Parallels.

Comment / Share »
Thursday, December 5 2013 1:21 PM

Open Weather App - "Xaver" Special

Author: matthias - Last modified: Friday, December 6 2013 2:56 PM

en angularjs  javacsript  weather  t3n  openweather app  xaver  storm

Some two weeks ago an article I wrote about AngularJS has been published in the latest issue of Germanys "t3n" tech magazine. The article covers some basic concepts and techniques of AngularJS and I decided (for whatever reason) to create a little example "weather forecast app" based on the platform "Open Weather Map".

Now with heavy storm "Xaver" arriving in Hamburg today I quickly decided to give this app a tiny "Xaver Special" update providing the current and forecast wind speed and more data for selected locations in Northern Germany.

Check it out: OpenWeather App Demo - Xaver Special

By the way:

Comment / Share »
Monday, December 2 2013 3:35 PM

AngularJS - Publikation im t3n-Magazin

Author: matthias - Last modified: Monday, December 2 2013 3:39 PM

de t3n  article  angularjs  javascript  openweathermap

Für das aktuelle t3n-Magazin, welches seit dem 27. November 2013 im Handel erhältlich ist, habe ich wieder mal einen Artikel geschrieben.

Diesmal habe ich mich Googles JavaScript-Framwork AngularJS angenommen. Bei der Ausarbeitung des Artikels ist als begleitendes Praxis-Beispiel eine kleine feine "Wetter-App" basierend auf dem Service von OpenWeatherMap entstanden.

Viel Spaß beim Lesen - Kritik willkommen!

Comment / Share »
Monday, August 26 2013 10:08 AM

yanexbo - yet another node/express boilerplate

Author: matthias - Last modified: Monday, August 26 2013 10:19 PM

en node  express  mongoose  jade  boilerplate  github

After developing a couple of node applications utilizing express, mongoose and jade, I decided to create and publish a simple node/express boilerplate called yanexbo.

What's the purpose of it? yanexbo is a minimalistic boilerplate which can be used as a quick start for your next node project using express, mongoose and the jade templating engine. It suggests a simple yet slightly opinionated set of files and directories giving some structure to your application. It can easily grow into any direction of node/express app.

Clone or fork it from github:

https://github.com/atufkas/yanexbo

Comments, ideas, suggestions, improvements, pull requests are welcome!

Comment / Share »
Thursday, August 22 2013 9:09 AM

Artikel zu "Meteor" im t3n-Magazin

Author: matthias - Last modified: Thursday, August 22 2013 9:11 AM

de meteor  article  t3n  javascript

Vor einiger Zeit kam Print-Redaktionsleiter Luca Caracciolo vom t3n-Magazin auf mich zu und frug mich, ob ich Lust hätte, einen Artikel zum JS-Framework Meteor zu schreiben.

Da ich mich bis dato mit dem Framework auseinandersetze, gerne schreibe und JavaScript sowieso immer mehr ins Zentrum meines Coding-Alltags rückt, erklärte ich mich gerne bereit. Der Artikel erscheint am 27. August im gedruckten t3n-Magazin Nr. 33.

Als Vorgeschmack auf das Magazin ist der Artikel aber auch bereits online in voller Länge verfügbar: Einblick in die Full-Stack-JavaScript-Plattform für das Echtzeit-Web .

Der Beitrag versteht sich als Einführung, Überblick und Wegweiser zur technologischen Einordnung und richtet sich somit an ein breites Publikum von allgemein Technologie-Interessierten - ähnlich wie mein erster Blog-Artikel zu Meteor aus dem Herbst letzten Jahres.

Viel Spaß beim Lesen!

Comment / Share »