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 »
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 »
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 »
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 »
Tuesday, May 28, 2013 3:50 PM

Vortrag "JavaScript überall"

Author: matthias - Last modified: Thursday, November 14, 2013 9:36 AM

de javascript javascript everywhere  talk  introduction  nodejs

Im vergangenen halben Jahr hat sich meine Arbeit mit JavaScript weiter intensiviert und zur Zeit arbeite ich parallel an verschiedenen JS-Projekten (node JS, Ext JS, express/Backbone). Zwischenzeitig habe ich einen Vortrag ausgearbeitet.

Vor zwei Wochen hielt ich im Rahmen der regelmässig organisierten Seminarvormittage in der Bürogemeinschaft "Freunde der Medien" einen Vortrag über Vergangenheit, Gegenwart und Zukunft der großen weiten Welt von JavaScript mit dem Titel "JavaScript überall".

Das primäre Ziel und letztlich die größte Herausforderung dabei war, ein relativ heterogenes Publikum aus Codern und _Überhauptnicht-Codern zu erreichen und für die zunehmende Bedeutung von JavaScript in der modernen, bunten und vernetzten "App-Welt" zu sensibilisieren. _

Erfreulich: Ein ausnahmslos gutes Feedback bestätigte mir, dass ich die ca. 18 Teilnehmer erfolgreich auf die kleine JS-Reise mitnehmen konnte.

JavaScript überall

* Interesse geweckt? *

Der Vortrag eignet sich als allgemeine Einführung in das Thema "JavaScript im modernen Web". Es betrachtet die Sprache und Wirkungsfelder aus unterschiedlichen Blickwinkeln und für einen Zielgruppen-Mix aus Projektverantwortlichen, Entscheidern und Programmierern. Weitab von Klischees, die vor allem aus den "Browser-Kindertagen" von JavaScript stammen, geht es um die Beantwortung der Frage, welche Möglichkeiten die Sprache, ihre professionelle Adaption auf Serverseite (NodeJS) und die Verwendung in diversen Frameworks und Software-Ökosystemen bietet – und in der zweiten Dekade des 21. Jahrhunderts voraussichtlich noch bieten wird.

Wenn Sie an diesem Vortrag oder einem ihrer Interessengruppe angepassten Event – in Talk- oder Seminar-Form – Interesse haben sollten, kontaktieren Sie mich gerne!

* ...aus dem Inhalt: *

# "JavaScript überall" - aus dem Inhalt:
var jsUeberall = {
  type: 'Talk',
  audience: 'Everyone',
  chapter: [
    'Dynamik im Browser + Historisches',
    'Server Side JavaScript: Node.js & Co',
    'Kommunikation ist alles - JSON',
    'Echtzeit-Anwendung am Beispiel Meteor JS',
    'Fragen & Antworten'
  ]
}
Comment / Share »
Tuesday, February 5, 2013 4:52 PM

Re-adding setOptions() to prototype

Author: matthias - Last modified: Tuesday, February 5, 2013 4:52 PM

en prototype  scriptaculous  javascript fixlet  code

If you - like me - have to deal with legacy code of web applications that runs for years at customers' satisfaction but suddenly causes problems as soon as newer browser versions (that e.g. lack of some DOM compatibility modes) are used... and if you're making extensive use of scriptaculous and/or prototype - like I once did - read on.

This one is quite special but eventually the problem description and solution is helpful to anyone.

Problem description

There may exist legacy JS code in the wild that wants to make use of prototype library versions >= 1.7.0 (e.g. in combination with scriptaculous >= 1.9.0 for IE compatibility reasons in conjunction with scriptaculous' dragdrop.js) but fails to behave correctly because custom code extends prototype classes and relies on the old setOptions() method originally provided by Ajax.Base.prototype.

So, if you recently upgraded from prototype 1.5.x or scriptaculous 1.7.x to a later version and experience problems with your application: Instead of refactoring the old code, this one may help out as a quick fix.

Code

Fork this code on GitHub

/**
 *  prototype-setoptions.fixlet.js
 *  
 *  Author:
 *     Matthias Lienau <matthias@mlienau.de>
 *
 *  Licensed under the MIT license:
 *    http://www.opensource.org/licenses/mit-license.php
 */
(function($) { 

  function getVersion(verString) {
    var v = verString.replace(/_.*|\./g, '');
    v = parseInt(v + '0'.times(4 - v.length));
    return verString.indexOf('_') > -1 ? v - 1 : v;
  }

  if ((typeof Prototype == 'undefined') || 
      (getVersion(Prototype.Version) <= getVersion('1.6.0'))) {
    throw('"prototype-setoptions-fixlet.js" only applicable for Prototype JavaScript framework >= 1.7.0. Skipping fixlet code.'); 
  }

  console.info('"prototype-setoptions-fixlet.js" detected Prototype version ' + Prototype.Version + '. Applying fixlet code.');

  Object.extend(Ajax.Base.prototype, {
    setOptions: function(options) {
      this.options = {
        method: 'post', 
        asynchronous: true, 
        contentType: 'application/x-www-form-urlencoded',
        encoding: 'UTF-8', 
        parameters: '', 
        evalJSON: true, 
        evalJS: true
      };  
      Object.extend(this.options, options || {});
    }
  });

})();

Usage

Just load the js as a "drop-in" additionally to loading prototype.js, for example:

<script src="/yourjsfolder/prototype-1.7.1.js" type="text/javascript" />
<script src="/yourjsfolder/prototype-setoptions-fixlet.js" type="text/javascript" />

Hope that's helpful - feel free to contact me on any questions.

Comment / Share »
Monday, October 8, 2012 11:22 PM

Meteor Web Plattform: Echtzeit ab Werk

Author: matthias - Last modified: Wednesday, December 23, 2015 12:02 AM

de meteor  nodejs  javascript platform  framework  realtime  startup

Seit einigen Monaten verfolge ich neugierig das Treiben der Meteor Development Group und die Fortschritte ihres quelloffenen Kernprojekts Meteor. Meteor ist eine konsequent auf JavaScript und node aufsetzende Web Application Platform. In diesem Post werde ich einen kleinen Überblick über die Hintergründe geben und ein paar Paradigmen anhand eines Beispiels erläutern.

Wer? Eine Handvoll Jungs aus Kalifornien. Mal wieder.

Das kleine ambitionierte Startup aus San Francisco hat sich mit ihrem Projekt nicht Geringeres auf die Fahne geschrieben, als einen gehörigen Anteil am Transformationsprozess und an den Basistechnologien der in den kommenden Jahren weiter massiv an Bedeutung gewinnenden Web-Applikationen bestreiten zu wollen. Wie im Valley bzw. der Bay Area bei solch vielversprechenden Ansätzen nicht unüblich, sind die Jungs (Geeks, Nerds) im Sommer 2012 von verschiedenen Investoren mit einer anständigen Summe an Kapital ausgestattet worden, so dass sie sich zumindest um die mittelfristige Weiterverfolgung ihrer Vision keine Sorgen zu machen brauchen.

Warum ich ausgerechnet bei Meteor genauer hinschaue

Meteor ist im Anfangsstadium, die API ändert sich noch häufig - allzu viel lässt sich über die Zukunft wirklich nicht voraussagen. Aber mir gefällt das "Mission statement" und die Vision der Gründer (ich mag Visionen und gehe deswegen nicht zum Arzt!). Sie liesse sich etwas flappsig in etwa wie folgt sinngemäss zusammenfassen:

Entwickle Web-Anwendungen extrem schnell und einfach, entwickle Back- und Frontend in einer einzigen Sprache, entwickle mit Leichtigkeit Echtzeitanwendungen und integriere Deine Lösung in andere Systeme und umgekehrt - tue dies alles im vollsten Vertrauen, dass Deine Anwendung jederzeit für eine beliebig große Anwenderzahl verfügbar ist, natürlich bei Traum-Antwortzeiten. Kümmere Dich nicht um Hardware oder etwaige Administrationsaufgaben wie ödes Tuning von SQL-Datenbanken!

Also genau das, wovon jeder Web-Entwickler schon lange träumt! Nun, vielleicht ist es an der Zeit, erstmal ein praktisches Beispiel zu betrachten.

Für die Hacker/Ungeduldigen: Das Beispiel "Leaderboard"

Zur Installation von Meteor inkl. aller Abhängigkeiten und Erstellung des Beispielprojekts "leaderboard" braucht man ein anständiges Betriebssystem, eine Shell und eine Prise Neugierde sowie Vertrauen:

$ (sudo) curl https://install.meteor.com | sh
$ meteor create --example leaderboard
$ cd leaderboard
$ meteor

Der Aufruf $ meteor startet die Anwendung lokal auf Port 3000. Öffnet man diese Anwendung nun in zwei unterschiedlichen Browserfenstern (http://localhost:3000), stellt diese nebeneinander und vergibt ein paar Punkte hier und da, sollte sich das Aha!-Erlebnis schnell einstellen.

Ein Deployment in der Meteor-Cloud ist auch gleich vorgesehen:

$ meteor deploy [my-fancy-leaderboard].meteor.com

Wobei [my-fancy-leaderboard] selbstverständlich durch einen individuellen Namen ersetzt werden sollte, den möglichst noch kein Zweiter benutzt. Hier residiert gerade (m)eine Standard-Installation des Leaderboard-Beispiels: http://ml-leaderboard.meteor.com/.

Ein paar Paradigmen und ein kurzer Blick unter die Haube

JS and Database Everywhere

Das Leaderboard-Beispiel besteht aus drei Dateien, welche die eigentliche Anwendung beschreiben: 47 Zeilen JavaScript, 35 Zeilen HTML (mit Handlebars-Templates) und 62 Zeilen CSS - unkomprimiert und mit Kommentaren. Ein Blick in die Datei leaderboard.js:

if (Meteor.is_client) {
  Template.leaderboard.players = function () {
    return Players.find({}, {sort: {score: -1, name: 1}});
  };
  ...
}
...
if (Meteor.is_server) {
  Meteor.startup(function () {
    if (Players.find().count() === 0) {
      var names = ["Ada Lovelace", "Grace Hopper", "Marie Curie",  ... ];
      for (var i = 0; i < names.length; i++)
        Players.insert({name: names[i], score: Math.floor(Math.random()*10)*5});
    }
  });
}

Die Prüfungen is_client sowie ìs_server lassen ein wesentliches Merkmal von Meteor erahnen: Nämlich die Grundannahme, dass wesentliche Objekte sinnvollerweise auf dem Server und im Client verfügbar gemacht werden sollten. Bemüht man im Browser die JavaScript-Console z.B. derart:

> Players;

so bekommt man ohne Umwege ein Objekt vom Typ Meteor.Collection zurückgeliefert, welches die Dokumente der Collection Players in der standardmässig verfügbaren MongoDB-Datenbank repräsentiert. Dies lässt schon so manches Programmiererherz höher schlagen.

Viele Entwickler werden bestätigen, dass es reichlich gute Gründe gibt, bestimmte Objekte und Funktionalität manchmal besser im Browser, machmal besser auf dem Server und oft am liebsten auf beiden Seiten verfügbar zu machen. Da wir hier ausschliesslich in JavaScript programmieren, ist der gewählte Ansatz naheliegend. Kein redundanter JS-Code muss extra geschrieben oder mittels irgendwelcher Compiler für den Browser erzeugt werden.

Data on the Wire, Realtime as default

Dies passt nun auch nahtlos zum von Meteor propagierten Prinzip Data on the Wire, nach welchem der Client niemals "fertig gerendertes" HTML erhalten soll, sondern lediglich die Nutzdaten selbst vom Sever übermittelt bekommt. HTML existiert in Form von Templates - natürlich bzw. gerade auch auf Client-Seite. Diese werden beim Aufruf der (Single Page) Applikation geladen. Die von Meteor generierten Objekt-Prototypen hierzu kann man sich wieder über die JS-Console anschauen:

> Template;

Nun kombiniere man dies mit dem nächsten Paradigma Realtime as Default und der Tatsache, dass Meteor standardmässig Web-Sockets bereithält. Das Ereignis "Veränderung in der Datenbank" könnte somit sofort und ohne Umwege in der View bzw. im View-Modell des Clients durchschlagen. Wer mag, gibt "Grace Hopper" der Players-Collection also mal satte 150 Punkte zusätzlich. Ach so, natürlich wieder direkt mittels der JS-Console des Browsers.

> Players.update(Players.findOne({name: 'Grace Hopper'}), {$inc: {score: 150}});  

Bang!

Es sind noch nicht alle Paradigmen wie z.B. die Latency Compensation erwähnt, aber als erster Überblick sollte es an dieser Stelle ausreichend sein.

Ein kleines Fazit. Bis hierher.

Allgemein betrachtet: Bei einer weiterhin kontinuierlich wachsenden Menge an Daten sowie ständig neuen Anforderungen an deren kurzfristige Evaluation, Aggregation, Integration in andere Dienste und Bereitstellung für sich dynamisch verändernde Nutzergruppen wird es technologische Antworten wie Meteor geben müssen. Und diese, so viel steht schon jetzt fest, müssen auf jeden Fall eine extrem agile und modulare Entwicklungsweise sowie eine unproblematische Bereitstellung in hochverfügbaren Cloud-Infrastrukturen ermöglichen. Das Ganze bei überschaubaren Kosten, versteht sich.

Ein spezifisches Projekt wie Meteor, das seine Einfachheit und Mächtigkeit mit Trommelwirbel propagiert (wie seinerzeit vielleicht Rails) und in Wirklichkeit erst in den Anfängen und jenseits der Produktionsreife steckt, muss nicht zwingend eine große Zukunft besitzen. Gleichwohl traue ich den Köpfen dahinter weit mehr als einen Achtungserfolg zu. Meteor ist mindestens ein wichtiger Trendindikator für die Frage nach dem "Quo vadis, Web?". Das Projekt zeigt schon in diesem frühen Stadium einen sehr eleganten Weg für die Entwicklung und Bereitstellung moderner Applikationen, die auf Web-Standards basieren und Echtzeit- sowie Kollaborations-Anforderungen von Haus aus bedienen.

Ich schaue jedenfalls weiterhin gespannt auf die Entwicklung dieses Projekts!

Anmerkung: An dieser Stelle sollte ich noch betonen, dass ich keine Diskussion um z.B. unternehmenskritische Prozesse, Datenintegrität und Transaktionssicherheit in sensiblen Systemumgebungen einbringen möchte. Das ist eine andere Betrachtungsweise und hier beschränke ich mich zunächst auf die Anwendungsfälle der "agilen Web-Applikationen für jedermann".

Comment / Share »
Monday, October 1, 2012 8:52 PM

Das JS Date-Objekt: -1 für den Monat!

Author: matthias - Last modified: Wednesday, October 3, 2012 10:58 AM

de javascript date  month  momentjs

Ja ja, mich legt man nur zweimal rein. Und so ist es mir also gerade tatsächlich wiederholt passiert, dass ich das JS Date-Objekt falsch initialisiert habe. Genauer gesagt geht es um den Wert für den Monat in der Standard-Konstruktion new Date(year, month, day, hours, minutes, seconds, milliseconds). So weit wirkt das unverfänglich.

Nun führt aber die folgende Initialisierung

var year = 2012:
var month = 10;
var day = 1;
var myDate = new Date(year,month,day);
console.log("myDate: ",myDate);

nicht etwa zu einem Datums-Objekt mit der Repräsentation des Datums 01.10.2012 wie die Log-Ausgabe beweist:

myDate:  Thu Nov 01 2012 00:00:00 GMT+0100 (CET)

Das liegt daran, dass die interne Repräsentation des Monats mit dem Index 0 statt 1 beginnt. Ergo: Immer -1 geben. Bei Initialisierung durch einen Wert, der von aussen hereingegeben wird (und ein Monat durch die natürliche Monatszahl repräsentiert wird) machen wir also mal lieber Folgendes:

var myDate = new Date(year,parseInt(month) - 1,day);

Falls der Eingabewert z.B. aus einem Request-Parameter stammt, dann hilft parseInt() bei der Umwandlung in den primitiven Typ number.

By the way: Eine ganz wunderbare JS-Bibliothek für etliche Anforderungen an das Datums-Handling ist moment.js, welche ich auch hier in meiner node Blog-Engine einsetze.

Comment / Share »