<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[nehalist.io]]></title><description><![CDATA[About things]]></description><link>https://nehalist.io/</link><image><url>https://nehalist.io/favicon.png</url><title>nehalist.io</title><link>https://nehalist.io/</link></image><generator>Ghost 1.24</generator><lastBuildDate>Sun, 24 Jun 2018 21:58:17 GMT</lastBuildDate><atom:link href="https://nehalist.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Polling in Angular]]></title><description><![CDATA[How to implement polling in Angular with a PHP Twitter API backend.]]></description><link>https://nehalist.io/polling-in-angular/</link><guid isPermaLink="false">5aeedccf7f2dc038d5f2a48b</guid><category><![CDATA[angular]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Mon, 21 May 2018 15:43:54 GMT</pubDate><media:content url="https://nehalist.io/content/images/2018/05/angular-logo.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2018/05/angular-logo.png" alt="Polling in Angular"><p>In case you need to update data without refreshing your browser you've got different options. One of them is <em>polling</em>, which means continuously requesting data from the server. In case you haven't access to <a href="https://en.wikipedia.org/wiki/WebSocket">sockets</a> polling is a neat and simple way to update data without any user interaction required.</p>
<h2 id="pollingvswebsockets">Polling vs. WebSockets</h2>
<p>Before diving right into how to implement polling in Angular let's take quick glance at the difference between polling and sockets. I've always liked the approach of explaining it via the analogy of a dialog between client and server.</p>
<p>When polling data the dialog would be:</p>
<blockquote>
<p>[10:00:00] <em>Client</em>: Is there something new?<br>
[10:00:00] <em>Server</em>: No.<br>
[10:00:05] <em>Client</em>: Is there something new?<br>
[10:00:05] <em>Server</em>: No.<br>
[10:00:10] <em>Client</em>: Is there something new?<br>
[10:00:10] <em>Server</em>: Yes.</p>
</blockquote>
<p>The client (in our case most likely our JavaScript) is <em>&quot;asking&quot;</em> the server in a defined interval for new data. It may even happen that there <em>is</em> new data but we're getting the data a few seconds later, which means polling is not really <em>realtime</em>.</p>
<p>On the otherhand WebSockets work differently:</p>
<blockquote>
<p>[10:00:00] <em>No communication between client and server.</em><br>
[10:00:05] <em>No communication between client and server.</em><br>
[10:00:10] <em>Server</em>: Dude, there's new data!<br>
[10:00:10] <em>Client</em>: Yeah!</p>
</blockquote>
<p>In this case it's the other way round; instead of the client permanently asking for new data the server is simply informing the client whenever new data is available. Data is (very likely) received instantaneously - or in other words this approach is <em>realtime</em>.</p>
<p>From a logical perspective of view the sockets approach do indeed make more sense. Remembering the time when my mother cooked for me she would have probably killed me if I'd asked every five seconds <em>&quot;Is dinner ready??&quot;</em> instead of me simply waiting for her to tell me <em>&quot;Dinner is ready!&quot;</em>.</p>
<p>So, why to use polling? Often you just don't have access to sockets. When working with Node you can simply use <a href="https://socket.io/">socket.io</a> to make use of sockets. PHP on the other hand makes it a bit more complicated, especially since the way PHP works isn't the best choice for such things. To compensate for this polling is often enough to simply update things on your client without having to refresh or require any other interaction. Keep in mind that if you're going to implement realtime applications (chats, collaboration tools, ...) sockets are most likely the way to go.</p>
<h2 id="ourapplication">Our application</h2>
<p>To show how polling is working in Angular we're going to implement a simple application which gets some tweets from Twitter.</p>
<h3 id="systemprerequisites">System prerequisites</h3>
<p>The example application was implemented using the following package versions:</p>
<blockquote>
<p>PHP <code>v7.0.28</code><br>
Angular CLI <code>v6.0.3</code><br>
rxjs <code>v6.1.0</code><br>
TypeScript <code>2.7.2</code></p>
</blockquote>
<p>You can find all used package versions in the <code>package.json</code> respectively the <code>composer.json</code> in the GitHub repository.</p>
<h2 id="server">Server</h2>
<p>We're going to use the <a href="https://github.com/dg/twitter-php">twitter-php</a> library to keep this as simple as always.</p>
<pre><code class="language-php">// server/index.php

&lt;?php
require_once 'vendor/autoload.php';

// Allow getting data from our API
header('Access-Control-Allow-Origin: *');

// Set our response to JSON
header('Content-type: application/json');

try {
    $twitter = new Twitter('&lt;YOUR TWITTER CONSUMER KEY&gt;', '&lt;YOUR TWITTER CONSUMER SECRET&gt;');
    
    // Search twitter for tweets
    $response = $twitter-&gt;request('search/tweets', 'GET', [
        'q' =&gt; 'javascript',
        'lang' =&gt; 'en',
        'count' =&gt; 5
    ]);
} catch(TwitterException $e) {
    $response = ['error' =&gt; $e-&gt;getMessage()];
}

exit(json_encode($response));
</code></pre>
<p>Of course you need to replace <code>&lt;YOUR TWITTER CONSUMER KEY&gt;</code> and <code>&lt;YOUR TWITTER CONSUMER SECRET&gt;</code> with proper values. To get these values register your application at the <a href="https://apps.twitter.com/">Twitter Application Management</a>.</p>
<p>We're going to use the built-in webserver of PHP to start this file:</p>
<pre><code>php -S localhost:8000
</code></pre>
<p>Opening <code>http://localhost:8000</code> searches for tweets containing the word <code>javascript</code> (specified via the <code>q</code> key) and returns a response like:</p>
<pre><code class="language-json">{
  &quot;statuses&quot;: [
    // a list of tweets
  ],
  &quot;search_metadata&quot;: {
    // search metadata
  }
}
</code></pre>
<p><em>Done</em>. Whenever you're requesting this you're most likely to get new tweets. Now we're going to poll this file and show some tweets.</p>
<h2 id="angularclient">Angular client</h2>
<p>Implementation of our client is fairly simple.</p>
<h3 id="models">Models</h3>
<blockquote>
<p><strong>Important:</strong> Managing models will be handled the way described in my post <a href="https://nehalist.io/working-with-models-in-angular/">Working with models in Angular</a>.</p>
</blockquote>
<p>For our application we're going to need three different models: one for the response, one for a single status and one for a single author. Since the hierachy begins with the response let's implement this model at first:</p>
<p><em>Note</em>: For the sake of simplicity we're going to ignore many of the properties we're getting from our API.</p>
<pre><code class="language-typescript">// models/twitter-response.model.ts

import {Deserializable} from &quot;./deserializable.model&quot;;
import {Status} from &quot;./status.model&quot;;

interface SearchMetadata {
  completed_in: number;
  max_id: number;
  max_id_str: string;
  next_results: string;
  query: string;
  refresh_url: string;
  count: number;
  since_id: number;
  since_id_str: string;
}

export class TwitterResponse implements Deserializable {
  statuses: Status[];
  searchMetadata: SearchMetadata;

  deserialize(input: any) {
    Object.assign(&lt;any&gt;this, input);

    input.statuses &amp;&amp; (this.statuses = input.statuses.map((status: Status) =&gt; new Status().deserialize(status)));

    return this;
  }
}
</code></pre>
<p>A single status is represented by the following model:</p>
<pre><code class="language-typescript">// models/status.model.ts

import {Deserializable} from &quot;./deserializable.model&quot;;
import {User} from &quot;./user.model&quot;;

export class Status implements Deserializable {
  id: number;
  text: string;
  user: User;

  deserialize(input: any) {
    Object.assign(&lt;any&gt;this, input);

    return this;
  }
}
</code></pre>
<p>The last model we're going to need is the one representing the user (or <em>author</em>):</p>
<pre><code class="language-typescript">// models/user.model.ts

import {Deserializable} from &quot;./deserializable.model&quot;;

export class User implements Deserializable {
  id: number;
  name: string;
  screen_name: string;

  deserialize(input: any) {
    Object.assign(&lt;any&gt;this, input);

    return this;
  }
}
</code></pre>
<p>That's it for our models. Now</p>
<h3 id="service">Service</h3>
<p>Next we're going to need a service which requests the data from our API:</p>
<pre><code class="language-typescript">import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {TwitterResponse} from &quot;../models/twitter-response.model&quot;;
import {Observable} from &quot;rxjs/internal/Observable&quot;;
import {map} from &quot;rxjs/operators&quot;;

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  constructor(private http: HttpClient) {
  }

  getTweets(): Observable&lt;TwitterResponse&gt; {
    return this.http.get&lt;TwitterResponse&gt;('http://localhost:8000')
      .pipe(
        map(res =&gt; new TwitterResponse().deserialize(res))
      );
  }
}
</code></pre>
<p>Subscribing to our <code>Observable</code> will now give us an instance of <code>TwitterResponse</code>.</p>
<h3 id="component">Component</h3>
<p>The component will handle the polling using <code>RxJS</code>. The component will implement the <code>OnInit</code> interface where the polling will be started.</p>
<pre><code class="language-typescript">// app.component.ts

import {Component, OnInit} from '@angular/core';
import {ApiService} from &quot;./services/api.service&quot;;
import {interval} from &quot;rxjs/internal/observable/interval&quot;;
import {startWith, switchMap} from &quot;rxjs/operators&quot;;
import {Status} from &quot;./models/status.model&quot;;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  statuses: Status[];

  constructor(private apiService: ApiService) {
  }

  ngOnInit() {
    interval(5000)
      .pipe(
        startWith(0),
        switchMap(() =&gt; this.apiService.getTweets())
      )
      .subscribe(res =&gt; this.statuses = res.statuses})
    ;
  }
}
</code></pre>
<p><code>interval</code> is an observable which is <a href="https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md">piped</a>. It's pretty obvious what happens here: every 5 seconds (starting at <code>0</code> to make an &quot;initial call&quot;) the <code>apiService.getTweets()</code> is called and the components property <code>statuses</code> is re-assigned.</p>
<blockquote>
<p><strong>Important:</strong> In case you're using an older version of Angular your implementation would look like this:</p>
</blockquote>
<pre><code class="language-typescript">Observable
  .interval(5000)
  .startWith(0)
  .switchMap(() =&gt; this.apiservice.getTweets())
  .subscribe(res =&gt; this.statuses = res.statuses);
</code></pre>
<h3 id="template">Template</h3>
<p>The last part is the template, which is just iterating over our <code>statuses</code> and display our tweets:</p>
<pre><code class="language-html">&lt;ul&gt;
    &lt;li *ngFor=&quot;let status of statuses&quot;&gt;
        &lt;blockquote class=&quot;twitter-tweet&quot;&gt;
            &lt;p&gt;{{status.text}}&lt;/p&gt;
            by &lt;a href=&quot;https://twitter.com/{{status.user.screen_name}}&quot;&gt;{{status.user.name}} (@{{status.user.screen_name}})&lt;/a&gt;
        &lt;/blockquote&gt;
    &lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>Thanks to Angular the view is updated automatically everytime new tweets are coming in:</p>
<p><img src="https://nehalist.io/content/images/2018/05/polling.gif" alt="Polling in Angular"></p>
<h2 id="conclusion">Conclusion</h2>
<p>As you can see it's fairly easy to do polling (with required additional tasks like updating our view) in Angular.</p>
<p>This technique can be used for various things like voting systems, messaging, etc.. And, as always, you can find the entire source code for this post on <a href="https://github.com/nehalist/polling-in-angular">GitHub</a>.</p>
<h3 id="ps">P.S.</h3>
<p>I've promised to explain why there hasn't been a blog post for such a long time. To keep the answer to this as simple as possible: I'm no longer single.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Dependency Injection in TypeScript]]></title><description><![CDATA[<div class="kg-card-markdown"><p>One thing I really like about mature frameworks is that they all implement some kind of dependency injection. Recently I've played around with this technology in TypeScript to get a better understanding of <em>how</em> it works beneath the surface.</p>
<h2 id="whatisdependencyinjectiondi">What is dependency injection (DI)?</h2>
<p>In case you have no idea</p></div>]]></description><link>https://nehalist.io/dependency-injection-in-typescript/</link><guid isPermaLink="false">5a75e702fdb03d1130b34a65</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[design]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Sun, 04 Feb 2018 21:16:47 GMT</pubDate><media:content url="https://nehalist.io/content/images/2018/02/typescript.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2018/02/typescript.png" alt="Dependency Injection in TypeScript"><p>One thing I really like about mature frameworks is that they all implement some kind of dependency injection. Recently I've played around with this technology in TypeScript to get a better understanding of <em>how</em> it works beneath the surface.</p>
<h2 id="whatisdependencyinjectiondi">What is dependency injection (DI)?</h2>
<p>In case you have no idea what DI is, I <strong>highly</strong> recommend to get <a href="https://en.wikipedia.org/wiki/Dependency_injection">in touch</a> with it. Since this post should not be about the <em>What?</em> but more about the <em>How?</em> let's try to keep this as simple possible at this point:</p>
<blockquote>
<p>Dependency injection is a technique whereby one object supplies the dependencies of another object.</p>
</blockquote>
<p><em>Quote from <a href="https://en.wikipedia.org/wiki/Dependency_injection">Wiki</a></em></p>
<p>What does that mean? Instead of manually constructing your objects some <em>piece</em> (often called <em>Injector</em>) of your software is responsible for constructing objects.</p>
<p>Imagine the following code:</p>
<pre><code class="language-typescript">class Foo {
}

class Bar {
  foo: Foo;
  
  constructor() {
    this.foo = new Foo();
  }
}

class Foobar {
  foo: Foo;
  bar: Bar;
  
  constructor() {
    this.foo = new Foo();
    this.bar = new Bar();
  }
}
</code></pre>
<p>This is <em>bad</em> for multiple reasons like having direct and non-exchangable dependencies between classes, testing would be <em>really</em> hard, following your code becomes really hard, re-usability of components becomes harder, etc.. Dependency Injection on the other hand <em>injects</em> dependencies into your constructor, making all these <em>bad</em> things obsolet:</p>
<pre><code class="language-typescript">class Foo {
}

class Bar {
  constructor(foo: Foo) {
  }
}

class Foobar {
  constructor(foo: Foo, bar: Bar) {
  }
}
</code></pre>
<p><em>Better</em>.</p>
<p>To get an instance of <code>Foobar</code> you'd need to construct it the following way:</p>
<pre><code class="language-typescript">const foobar = new Foobar(new Foo(), new Bar(new Foo()));
</code></pre>
<p><em>Not cool.</em></p>
<p>By using an <em>Injector</em>, which is responsible for creating objects, you can simply do something like:</p>
<pre><code class="language-typescript">const foobar = Injector.resolve&lt;Foobar&gt;(Foobar); // returns an instance of Foobar, with all injected dependencies
</code></pre>
<p><em>Better.</em></p>
<p>There are numerous resons about <em>why</em> you should dependency injection, including testability, maintainability, readability, etc.. Again, if you don't know about it yet, it's past time to learn something essential.</p>
<h2 id="dependencyinjectionintypescript">Dependency injection in TypeScript</h2>
<p>This post will be about the implementation of our very own (and very basic)  <code>Injector</code>. In case you're just looking for some existing solution to get DI in your project you should take a look at <a href="http://inversify.io/">InversifyJS</a>, a pretty neat IoC container for TypeScript.</p>
<p>What we're going to do in this post is we'll implement our very own Injector class, which is able to resolve instances by injecting all necessary dependencies. For this we'll implement a <code>@Service</code> decorator (you might know this as <code>@Injectable</code> if you're used to Angular) which defines our services and the actual <code>Injector</code> which will resolve instances.</p>
<p>Before diving right into the implementation there might be some things you should know about TypeScript and DI:</p>
<h3 id="reflectionanddecorators">Reflection and decorators</h3>
<p>We're going to use the  <a href="https://www.npmjs.com/package/reflect-metadata">reflect-metadata</a> package to get <a href="https://en.wikipedia.org/wiki/Reflection_(computer_programming)">reflection capabilities</a> at runtime. With this package it's possible to get information about how a class is implemented - an example:</p>
<pre><code class="language-typescript">const Service = () : ClassDecorator =&gt; {
  return target =&gt; {
    console.log(Reflect.getMetadata('design:paramtypes', target));
  };
};

class Bar {}

@Service()
class Foo {
  constructor(bar: Bar, baz: string) {}
}
</code></pre>
<p>This would log:</p>
<pre><code>[ [Function: Bar], [Function: String] ]
</code></pre>
<p>Hence we do know about the required dependencies to inject. In case you're confused why <code>Bar</code> is a <code>Function</code> here: I'm going to cover this in the next section.</p>
<p><strong>Important</strong>: it's important to note that classes <em>without</em> decorators do not have any metadata. This seems like a design choice of <code>reflect-metadata</code>, though I'm not certain <a href="https://stackoverflow.com/questions/48547005/why-is-reflect-metadata-only-working-when-using-a-decorator/">about the reasoning behind it</a>.</p>
<h3 id="thetypeoftarget">The type of <code>target</code></h3>
<p>One thing I was pretty confused about at first was the type of <code>target</code> of my <code>Service</code> decorator. <code>Function</code> seemed odd, since it's obviously an <code>object</code> instead of a function. But that's because of how JavaScript works; classes are just <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">special functions</a>:</p>
<pre><code class="language-typescript">class Foo {
    constructor() {
        // the constructor
    }
    bar() {
        // a method
    }
}
</code></pre>
<p>Becomes</p>
<pre><code class="language-javascript">var Foo = /** @class */ (function () {
    function Foo() {
        // the constructor
    }
    Foo.prototype.bar = function () {
        // a method
    };
    return Foo;
}());
</code></pre>
<p>After compilation.</p>
<p>But <code>Function</code> is nothing we'd want to use for a type, since it's way too generic. Since we're not dealing with an actual instance at this point we need a type which describes what type we get after invoking our target with <code>new</code>:</p>
<pre><code class="language-typescript">interface Type&lt;T&gt; {
  new(...args: any[]): T;
}
</code></pre>
<p><code>Type&lt;T&gt;</code> is able to tell us what an object is instances of - or in other words: what are we getting when we call it with <code>new</code>. Looking back at our <code>@Service</code> decorator the actual type would be:</p>
<pre><code class="language-typescript">const Service = () : ClassDecorator =&gt; {
  return target =&gt; {
    // `target` in this case is `Type&lt;Foo&gt;`, not `Foo`
  };
};
</code></pre>
<p>One thing which bothered me here was <code>ClassDecorator</code>, which looks like this:</p>
<pre><code class="language-typescript">declare type ClassDecorator = &lt;TFunction extends Function&gt;(target: TFunction) =&gt; TFunction | void;
</code></pre>
<p>That's unfortunate, since we now do know the type of our object. To get a more flexible and generic type for class decorators:</p>
<pre><code class="language-typescript">export type GenericClassDecorator&lt;T&gt; = (target: T) =&gt; void;
</code></pre>
<h3 id="interfacesaregoneaftercompilation">Interfaces are gone after compilation</h3>
<p>Since interfaces are not part of JavaScript they simply disappear after your TypeScript is compiled. Nothing new, but that means we <strong>can't</strong> use interfaces for dependency injection. An example:</p>
<pre><code class="language-typescript">interface LoggerInterface {
  write(message: string);
}

class Server {
  constructor(logger: LoggerInterface) {
    this.logger.write('Service called');
  }
}
</code></pre>
<p>There'll be no way for our Injector to know what to inject here, since the interface is gone at runtime.</p>
<p>That's actually a pity, because it means we always have to type-hint our <em>real</em> classes instead of interfaces. Especially when it comes to testing this may be become really unforunate.</p>
<p>There are workarounds, e.g. using classes instead of interfaces (which feels pretty weird and takes away the meaningfulness of interfaces) or something like</p>
<pre><code class="language-typescript">interface LoggerInterface {
  kind: 'logger';
}

class FileLogger implements LoggerInterface {
  kind: 'logger';
}
</code></pre>
<p>But I really don't like this approach, since its redundant and pretty ugly.</p>
<h3 id="circulardependenciescausestrouble">Circular dependencies causes trouble</h3>
<p>In case you're trying to do something like:</p>
<pre><code class="language-typescript">@Service()
class Bar {
  constructor(foo: Foo) {}
}

@Service()
class Foo {
  constructor(bar: Bar) {}
}
</code></pre>
<p>You'll get a <code>ReferenceError</code>, telling you:</p>
<pre><code>ReferenceError: Foo is not defined 
</code></pre>
<p>The reason for this is quite obvious: <code>Foo</code> doesn't exist at the time TypeScript tries to get information on <code>Bar</code>.</p>
<p>I don't want to go into detail here, but one possible workaround would be implementing something like Angulars <a href="https://github.com/angular/angular/blob/master/packages/core/src/di/forward_ref.ts">forwardRef</a>.</p>
<h2 id="implementingourveryowninjector">Implementing our very own Injector</h2>
<p>Okay, enough theory. Let's implement a very basic Injector class.</p>
<p>We're going to use all the things we've learned from above, starting with our <code>@Service</code> decorator.</p>
<h3 id="theservicedecorator">The <code>@Service</code> decorator</h3>
<p>We're going to decorate all services, otherwise they wouldn't emit meta data (making it impossible to inject dependencies).</p>
<pre><code class="language-typescript">// ServiceDecorator.ts

const Service = () : GenericClassDecorator&lt;Type&lt;object&gt;&gt; =&gt; {
  return (target: Type&lt;object&gt;) =&gt; {
    // do something with `target`, e.g. some kind of validation or passing it to the Injector and store them
  };
};
</code></pre>
<h3 id="theinjector">The <code>Injector</code></h3>
<p>The injector is capable of resolving requested instances. It may have additional capabilities like storing resolved instances (I like to call them <em>shared instances</em>), but for the sake of simplicity we're gonna implement it as simple as possible for now.</p>
<pre><code class="language-typescript">// Injector.ts

export const Injector = new class {
  // Injector implementation
};
</code></pre>
<p>The reason for exporting a constant instead of a class (like <code>export class Injector [...]</code>) is that our Injector is a <a href="https://en.wikipedia.org/wiki/Singleton_pattern">singleton</a>. Otherwise we'd never get the same instance of our <code>Injector</code>, meaning everytime you <code>import</code> the Injector you'll get an instance of it which has no services registered. (<em>Like every singleton this has some downsides, especially when it comes to testing.</em>)</p>
<p>The next thing we need to implement is a method for resolving our instances:</p>
<pre><code class="language-typescript">// Injector.ts

export const Injector = new class {
  // resolving instances
  resolve&lt;T&gt;(target: Type&lt;any&gt;): T {
    // tokens are required dependencies, while injections are resolved tokens from the Injector
    let tokens = Reflect.getMetadata('design:paramtypes', target) || [],
        injections = tokens.map(token =&gt; Injector.resolve&lt;any&gt;(token));
    
    return new target(...injections);
  }
};
</code></pre>
<p>That's it. Our <code>Injector</code> is now able to resolve requested instances. Let's get back to our (now slightly extended) example at the beginning and resolve it via the <code>Injector</code>:</p>
<pre><code class="language-typescript">@Service()
class Foo {
  doFooStuff() {
    console.log('foo');
  }
}

@Service()
class Bar {
  constructor(public foo: Foo) {
  }

  doBarStuff() {
    console.log('bar');
  }
}

@Service()
class Foobar {
  constructor(public foo: Foo, public bar: Bar) {
  }
}

const foobar = Injector.resolve&lt;Foobar&gt;(Foobar);
foobar.bar.doBarStuff();
foobar.foo.doFooStuff();
foobar.bar.foo.doFooStuff();
</code></pre>
<p>Console output:</p>
<pre><code>bar
foo
foo
</code></pre>
<p>Meaning that our <code>Injector</code> successfully injected all dependencies. <em>Wohoo!</em></p>
<h3 id="conclusion">Conclusion</h3>
<p>Dependency injection is a powerful tool you should definitely utilise. This post is about <em>how</em> DI works and should give you a glimpse of how to implement your very own injector.</p>
<p>There are still many things to do. To name a few things:</p>
<ul>
<li>error handling</li>
<li>handle circular dependencies</li>
<li>store resolved instances</li>
<li>ability to inject more than constructor tokens</li>
<li>etc.</li>
</ul>
<p>But basically this is how an injector could work.</p>
<p>As said at the beginning I've just recently begun with digging in DI implementations. If there's anything bothering you about this article or how the injector is implemented feel free to tell me in the comments or via <a href="mailto:hello@nehalist.io">mail</a>.</p>
<p>And, as always, the entire code (including examples and tests) can be found on <a href="https://github.com/nehalist/di-ts">GitHub</a>.</p>
<h2 id="changelog">Changelog</h2>
<h4 id="12052018">12.05.2018</h4>
<ul>
<li>Changed description of DI, thanks to <a href="https://www.reddit.com/r/typescript/comments/7v7zzm/dependency_injection_in_typescript/dusps5z/">dpash</a>.</li>
<li>Removed fragments of storing capabilities, thanks to <a href="https://github.com/nehalist/di-ts/issues/1">vforv</a>.</li>
</ul>
</div>]]></content:encoded></item><item><title><![CDATA[Directly injecting data to Vue apps with Symfony/Twig]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Usually data for Vue apps come from APIs, but ocassionally it may happen that you're rendering a Twig template with all the data you need and which you want to pass to your Vue app - without implementing an additional API.</p>
<h2 id="usecase">Use case</h2>
<p>Think of a controller to edit a</p></div>]]></description><link>https://nehalist.io/directly-injecting-data-to-vue-apps-with-symfony-twig/</link><guid isPermaLink="false">5a6c7f7efdb03d1130b34a51</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[Symfony]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Twig]]></category><category><![CDATA[PHP]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Sat, 27 Jan 2018 16:40:28 GMT</pubDate><media:content url="https://nehalist.io/content/images/2018/01/symfony-vue.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2018/01/symfony-vue.png" alt="Directly injecting data to Vue apps with Symfony/Twig"><p>Usually data for Vue apps come from APIs, but ocassionally it may happen that you're rendering a Twig template with all the data you need and which you want to pass to your Vue app - without implementing an additional API.</p>
<h2 id="usecase">Use case</h2>
<p>Think of a controller to edit a user, where the actual form is a standalone Vue app:</p>
<pre><code class="language-php">namespace App\Controller;

class EditRulesController
{
    public function indexAction(User $user)
    {
        // additional and mighty code
        return $this-&gt;render('user/edit.html.twig', [
            'user' =&gt; $user
        ]);
    }
}
</code></pre>
<p>In addition your twig template (<code>user/edit.html.twig</code>):</p>
<pre><code class="language-html">{% block body %}
&lt;h1&gt;Editing user {{user.name}}&lt;/h1&gt;
&lt;div id=&quot;user-edit-app&quot;&gt;&lt;/div&gt;
{% endblock }
</code></pre>
<p>To make your form <a href="https://vuejs.org/v2/guide/reactivity.html">reactive</a> instead of just a static standard form you may use a Vue app:</p>
<pre><code class="language-javascript">new Vue({
  el: '#user-edit-app',
  data: {
    username: ''
  },
  template: '&lt;div class=&quot;user-edit-form&quot;&gt;' + 
  	'&lt;input type=&quot;text&quot; v-model=&quot;username&quot;&gt;' +
    '&lt;span style=&quot;display: block;&quot;&gt;How cool is your name: {{coolness}}&lt;/span&gt;' +
    '&lt;input type=&quot;submit&quot; v-on:click=&quot;send&quot;&gt;' +
  '&lt;/div&gt;',
  computed: {
  	coolness: function() {
    	switch(this.username.toLowerCase()) {
      	case 'nehalist':
        case 'kevin':
        	return 'Pretty cool';
        case 'bob':
        	return 'Awesome!';
        case 'ajit pai':
        	return 'Terrible';
      	default:
        	return 'Not cool';
      }
    }
  },
  methods: {
    send: function() {
    	// send your form ...
    }
  }
});
</code></pre>
<p><em>Probably the mightiest thing I've ever implemented.</em></p>
<p>After your app is rendered you'll see something like this:</p>
<p><img src="https://nehalist.io/content/images/2018/01/vuenameapp-1.gif" alt="Directly injecting data to Vue apps with Symfony/Twig"></p>
<p>The problem now: since you've already rendered your twig template you do already know the <code>name</code> of the user you're editing. But how to get the name (or even the entire <code>User</code> object) into your vue app and your form? Glady that's pretty easy.</p>
<h2 id="utilisingbeforemountanddataattributestoinjectdata">Utilising <code>beforeMount</code> and <code>data</code> attributes to inject data</h2>
<p>First let's inject the data to our app container (in the twig template):</p>
<pre><code class="language-html">{% block body %}
&lt;h1&gt;Editing user {{user.name}}&lt;/h1&gt;
&lt;div id=&quot;user-edit-app&quot; data-name=&quot;{{ user.name }}&quot;&gt;&lt;/div&gt;
{% endblock }
</code></pre>
<p>To get access to our data within our view app we're going to utilise Vue's <a href="https://vuejs.org/v2/api/#beforeMount"><code>beforeMount</code></a> method:</p>
<pre><code class="language-javascript">new Vue({
  el: '#user-edit-app',
  data: {
    username: ''
  },
  // [...] `template` &amp; `computed` truncated
  beforeMount: function() {
    this.username = this.$el.attributes['data-name'].value;
  }
});
</code></pre>
<p>That's it. Now our app renders with the username input already being filled with the proper name.</p>
<p><strong>Note</strong>: This method does <em>not</em> work with server-side rendering, since the <code>beforeMount</code> method is never called.</p>
<h2 id="gettingtheentireuserobject">Getting the entire user object</h2>
<p>In case you're wanting the entire user object within your Vue app you need to serialize your user object and parse it within your Vue app.</p>
<p>You're either using the <a href="https://symfony.com/doc/current/components/serializer.html">Serializer</a> component, or implement a very simple <code>toArray</code> method within your entity. For the sake of simplicity we're going for latter in this article, but in the real world I'd suggest using serializers for this:</p>
<pre><code class="language-php">// src/Entity/User.php

class User
{
    protected $name;
    
    // [...] truncated setters, ...
    
    public function getName()
    {
        return $this-&gt;name;
    }
    
    public function toArray()
    {
        return [
            'name' =&gt; $this-&gt;getName()
        ];
    }
}
</code></pre>
<p>Your twig template now might look like this:</p>
<pre><code class="language-html">{% block body %}
&lt;h1&gt;Editing user {{user.name}}&lt;/h1&gt;
&lt;div id=&quot;user-edit-app&quot; data-user=&quot;{{ user.toArray|json_encode }}&quot;&gt;&lt;/div&gt;
{% endblock }
</code></pre>
<p>The <code>json_encode</code> is a <a href="https://twig.symfony.com/doc/2.x/filters/json_encode.html">Twig function</a> to return a value as JSON.</p>
<p>All you need to now is to slightly change our Vue apps <code>beforeMount</code> method:</p>
<pre><code class="language-javascript">new Vue({
  el: '#user-edit-app',
  data: {
    user: null,
    username: ''
  },
  // [...] `template` &amp; `computed` truncated
  beforeMount: function() {
    this.user = JSON.parse(this.$el.attributes['data-user']).value;
    this.username = this.user.name;
  }
});
</code></pre>
<p>It might be a good idea to validate the <code>data-</code> attributes before assigning it to your Vue instance, but basically this is enough to inject data without needing an additional API.</p>
</div>]]></content:encoded></item><item><title><![CDATA[VUSION (by SES-imagotag) product configurator: First Vue.js impressions]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I've never really talked about client projects - let's change that by taking a look at the <a href="https://vusion.ses-imagotag.com/">VUSION product configurator</a>, my most recent project for <a href="https://www.ses-imagotag.com/en/">SES-imagotag</a> which was also my first <a href="https://vuejs.org/">Vue.js</a> project.</p>
<h2 id="thefinishedproduct">The finished product</h2>
<p>Before diving into the tech stuff, you may want to take a look</p></div>]]></description><link>https://nehalist.io/vusion-product-configurator-first-vue-js-impressions/</link><guid isPermaLink="false">5a61f9ebfdb03d1130b34a45</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[Portfolio]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Fri, 19 Jan 2018 20:29:04 GMT</pubDate><media:content url="https://nehalist.io/content/images/2018/01/vusion.jpg" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2018/01/vusion.jpg" alt="VUSION (by SES-imagotag) product configurator: First Vue.js impressions"><p>I've never really talked about client projects - let's change that by taking a look at the <a href="https://vusion.ses-imagotag.com/">VUSION product configurator</a>, my most recent project for <a href="https://www.ses-imagotag.com/en/">SES-imagotag</a> which was also my first <a href="https://vuejs.org/">Vue.js</a> project.</p>
<h2 id="thefinishedproduct">The finished product</h2>
<p>Before diving into the tech stuff, you may want to take a look at the finished product at <a href="https://www.ses-imagotag.com/en/">vusion.ses-imagotag.com</a>. The website itself was implemented by a colleague, while I was responsible for implementing the product configurator.</p>
<p><img src="https://nehalist.io/content/images/2018/01/vusion-nb.png" alt="VUSION (by SES-imagotag) product configurator: First Vue.js impressions"></p>
<p><em>Look at this fancy notebook image!</em></p>
<h2 id="requirementsandtechnologystack">Requirements and technology stack</h2>
<p>Okay, let's get nerdy.</p>
<p>The product configurator had two interesting requirements: it should be embeddable with JavaScript and all its filters should be flexible (with all rules, mapping values, etc.) and be managed in an administration interface.</p>
<p>The administration was implemented in <em>&quot;plain&quot;</em> Symfony (using Symfony Form components, etc.) in combination with a mySQL database, while for the client we decided to give Vue.js a try. The only alternative would have been React, but I always wanted to try out Vue - which was no mistake by any means, but more on that later.</p>
<p><em>You won't find any screenshots of the filter administration. I guess I'm not allowed to post such screenshots, sorry.</em></p>
<h3 id="embeddablewithplainjavascript">Embeddable with plain JavaScript</h3>
<p>A fun and new thing for me to do was to create an application which can be embedded via plain JavaScript. To visualize how this is happening:</p>
<p><img src="https://nehalist.io/content/images/2018/01/embed-js-flowchart-1.png" alt="VUSION (by SES-imagotag) product configurator: First Vue.js impressions"></p>
<p><em>Another fancy image!</em></p>
<p>In short a very small loader script gathers client-related information and an array of <code>.css</code> and <code>.js</code> files required to run the application, which are then dynamically injected into the client. After loading is finished (usually just a few milliseconds) the Vue application (coming from the dynamically injected files) is injected in a specific <code>div</code> container.</p>
<p>Thanks to this the configurator can be embedded on basically every other website by just including the loader and the proper <code>div</code> container.</p>
<h2 id="vuejsimpressions">Vue.js impressions</h2>
<p>Vue did a great job for this application. Since this was my first Vue application everything was new for me - but nevertheless everything felt pretty straight-forward and, to my pleasure, little to no magic was involved. <em>Thinking of the first time when I used Angular and stumbled upon Observables and RXJs? Even Tom Riddle would have been pretty confused at first by the magic happening there.</em></p>
<p>The only thing which was kinda confusing at the beginning was how Vue is handling the <code>this</code> pointer. Speaking in code:</p>
<pre><code class="language-javascript">export default {
  data: function() {
    return {
      foo: 'bar'
    }
  },
  methods: {
    hello: function() {
      return this.foo;
    }
  }
}
</code></pre>
<p>Interestingly the <code>bar</code> function would return &quot;bar&quot; here, instead of complaining that <code>this.foo</code> is not defined. This is because how Vue handles <code>this</code>: the Vue instance proxies some of its properties (in case you're interesting see <a href="https://vuejs.org/v2/guide/instance.html">here</a>). This is pretty convenient once you're used to it, but it cost some <em>&quot;Whoops.&quot;</em>-moments when using arrow functions.</p>
<p>Everything else was, as said above, pretty straight-forward. Things worked like expected - nothing more I want from a framework. The app is structured pretty simple:</p>
<p><img src="https://nehalist.io/content/images/2018/01/vusion-app-structure-2.png" alt="VUSION (by SES-imagotag) product configurator: First Vue.js impressions"></p>
<p><em>In case you want to ask &quot;why the heck did he put curly brackets in the Filter Type component&quot;: I have no idea how to represent repetitive components in such a diagram. That my way of saying &quot;these things are repetitive!&quot;.</em></p>
<p>Filter type components are repetetive and depending on how filters are configured in the administration.</p>
<p>And, of course, the application is completely responsive:</p>
<p><img src="https://nehalist.io/content/images/2018/01/vusion-responsive.png" alt="VUSION (by SES-imagotag) product configurator: First Vue.js impressions"></p>
<p><em>Okay, that's the last fancy image.</em></p>
<h2 id="conclusion">Conclusion</h2>
<p>Even though this application was pretty small compared to the things I usually do, it was a really fun and interesting project. Vue is really fun and I'm definitely going again for it when there's a choice.</p>
<p>And gladly this project is publicly accessible so I'm allowed to talk about it - most of my applications are used internally (member databases, single sign on portals, ...), hence I can't really talk freely about them. Hopefully there'll be more of such projects in the future, I really enjoy writing such posts (<em>and making cool diagrams and fancy notebook/smartphone images!</em>).</p>
</div>]]></content:encoded></item><item><title><![CDATA[Downloading files from Ajax POST Requests]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Occasionally I stumble upon the need to download files from POST requests. An example would be generating PDF files, where the PDF content is dependent on the request. Interestingly this is not as straightforward as you may think, but it's not that hard either.</p>
<h2 id="asimpleserver">A simple server</h2>
<p>We're going to</p></div>]]></description><link>https://nehalist.io/downloading-files-from-post-requests/</link><guid isPermaLink="false">5a5a4025fdb03d1130b34a40</guid><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Sat, 13 Jan 2018 20:05:25 GMT</pubDate><media:content url="https://nehalist.io/content/images/2018/01/downloadpost.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2018/01/downloadpost.png" alt="Downloading files from Ajax POST Requests"><p>Occasionally I stumble upon the need to download files from POST requests. An example would be generating PDF files, where the PDF content is dependent on the request. Interestingly this is not as straightforward as you may think, but it's not that hard either.</p>
<h2 id="asimpleserver">A simple server</h2>
<p>We're going to implement a <em>really simple</em> server which is generating PDFs from the POST request:</p>
<pre><code class="language-php">&lt;?php
require_once 'vendor/autoload.php';

if($_SERVER['REQUEST_METHOD'] === 'POST') {
    header('Content-type: application/pdf');
    http_response_code(200);

    // Contents
    $pdfContent = !empty($_POST['content']) ? $_POST['content'] : 'no content specified';
    
    // Generate the PDOF
    $pdf = new FPDF();
    $pdf-&gt;AddPage();
    $pdf-&gt;SetFont('Arial','B',16);
    $pdf-&gt;Cell(40,10, $pdfContent);
    
    return $pdf-&gt;Output(null, 'foobar-' . time() . '.pdf');
}

// Bad method
http_response_code(405);
exit();
</code></pre>
<p><em>Note</em>: This code uses the <a href="https://github.com/Setasign/FPDF">FPDF</a> library to generate PDF files. For demonstration purposes the pdf is filled with the content from <code>$_POST['content']</code>.</p>
<p>FPDF automatically takes care about setting the <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition">Content-Disposition</a> to <code>attachment</code>. In case you don't use FPDF and need to set it manually simply add this before the output:</p>
<pre><code class="language-php">header('Content-Disposition: attachment; filename=&quot;filename.ext&quot;');
</code></pre>
<h2 id="downloadthefile">Download the file</h2>
<p>The more interesting thing about this is how the file is downloaded after sending the HTTP request. Let's dive straight into it:</p>
<pre><code class="language-html">&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset=&quot;utf-8&quot;&gt;
  &lt;title&gt;Download POST Request&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
Enter a text and click the button: &lt;input type=&quot;text&quot; id=&quot;content&quot; value=&quot;Text for the generated pdf&quot;&gt;
&lt;button id=&quot;download&quot;&gt;Send AJAX Request and download file&lt;/button&gt;

&lt;script&gt;
  document.getElementById('download').addEventListener('click', function () {
    var content = document.getElementById('content').value;
    var request = new XMLHttpRequest();
    request.open('POST', '../server/', true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.responseType = 'blob';

    request.onload = function() {
      // Only handle status code 200
      if(request.status === 200) {
        // Try to find out the filename from the content disposition `filename` value
        var disposition = request.getResponseHeader('content-disposition');
        var matches = /&quot;([^&quot;]*)&quot;/.exec(disposition);
        var filename = (matches != null &amp;&amp; matches[1] ? matches[1] : 'file.pdf');

        // The actual download
        var blob = new Blob([request.response], { type: 'application/pdf' });
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = filename;

        document.body.appendChild(link);

        link.click();

        document.body.removeChild(link);
      }
      
      // some error handling should be done here...
    };

    request.send('content=' + content);
  });
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p><em>Inhales deeply...</em></p>
<p>The actual download is done by creating a <a href="https://developer.mozilla.org/de/docs/Web/API/Blob/Blob"><code>Blob</code></a> object, which is used for a newly created <code>a</code> tag with a link to the created <code>Blob</code> object which is automatically clicked which ultimately opens the &quot;Save file&quot; dialog. Additionally it's appended to the <code>body</code> (which is a fix for Firefox) and is removed from the body afterwards (we don't want to have tons of invisible <code>a</code> tags on our body).</p>
<p>Well, <em>as easy as vertically centering content in divs</em>! (<em>Flexbox is cheating!</em>)</p>
<p>Keep in mind that this implementation uses plain JavaScript (to make it easier for everybody to follow the example), but the actual download works the same for most frameworks (jQuery, Vue, Angular, ...).</p>
<p>And, of course, you can find the entire implementation for this on <a href="https://github.com/nehalist/download-post-requests">GitHub</a>.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Twenty seven]]></title><description><![CDATA[<div class="kg-card-markdown"><p><em>Holy moly</em>, I'm overdue. Over a month ago was my 27th birthday, but I completely missed out the blog post to congratulate myself. It <em>deeply hurts my heart</em> that I failed at congratulating myself - but to make me feel better let me explain what happened and give you a</p></div>]]></description><link>https://nehalist.io/twenty-seven/</link><guid isPermaLink="false">59ef79fc6fc8cf171a7b080a</guid><category><![CDATA[Personal]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Sat, 02 Dec 2017 15:54:30 GMT</pubDate><media:content url="https://nehalist.io/content/images/2017/12/27-2.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2017/12/27-2.png" alt="Twenty seven"><p><em>Holy moly</em>, I'm overdue. Over a month ago was my 27th birthday, but I completely missed out the blog post to congratulate myself. It <em>deeply hurts my heart</em> that I failed at congratulating myself - but to make me feel better let me explain what happened and give you a brief summary of my year.</p>
<h2 id="workworkandmorework">Work, work and... more work</h2>
<p>The reason why I haven't been able to even visit my blog was the last project I worked on. It had a ridiculous deadline, which required to work on weekends, do overtime and all the stuff that makes you just want to go to bed when the day is done instead of writing blog posts about the same things you may have done the entire day.</p>
<p><strong>But</strong> we did it, the project went live on schedule and here I am again. <em>Wohoo!</em></p>
<h2 id="nobadnewsthisyear">No bad news this year!</h2>
<p>Does anybody remember my <a href="https://nehalist.io/twenty-six/">last birthday post</a>? It was horrendous. It was about surgeries, loosing money and dying cats. This time it's <strong>not</strong>!</p>
<p><em>No bad news this time</em>! Everything worked as expected; a pretty calm and quiet year, but that's exactly what I wanted. I'm still having the same job, still driving the same shitty car (<em>oh, did I mention that I don't like my car?</em>), no surgeries, no money losses, no pets died. The last thing was actually the other way round: I adopted a new cat!</p>
<p><img src="https://nehalist.io/content/images/2017/12/IMG_2564.JPG" alt="Twenty seven"></p>
<h2 id="fromadeveloperspointofview">From a developers point of view</h2>
<p>I learned a lot of new things; especially regarding Angular 2 (which was part of a project which took around 6 months) and Symfony (which is part of basically every project I'm working on).</p>
<p>I really fell in love with TypeScript, hence my next open source projects will probably be written in TS. That being said, I'm currently working on multiple new open source projects. Sadly development was really slowed down the last months - but I guess I'll have more time during winter holidays.</p>
<p>My current project for work involves <a href="https://vuejs.org/">VueJS</a>. I don't know much about it yet, but if I like it you can expect some VueJS posts here in the future.</p>
<h2 id="whatnext">What next?</h2>
<p>As mentioned above I'm currently working on multiple open source projects. I'll talk about them as soon as they left the <em>&quot;more than an idea and more than 3 files&quot;</em>-status.</p>
<p>One thing I'm currently thinking to do is video posts (vlogs or whatever you want to call them). Videos would enhance the way of communicating to a certain degree, but it also takes a lot of time. We'll see if this ever become reality.</p>
<p>Another thing is I'd like to blog more. At least 2 posts a month would be decent. My blog has between 200 and 400 visitors <em>every day</em> right now. This is insane, actually way more than I'd expect. But it's really appreciated to see that - gives a lot of motivation.</p>
<p>In short my plan is to make my upcoming year a bit more exciting. I really appreciated the quiet and calm year, but now it's time for a bit more action.</p>
<h2 id="ohandbeforeiforget">Oh, and before I forget...</h2>
<p><em>Belated happy birthday, me!</em></p>
<p><em>P.S. Please forgive me the usage of &quot;Holy moly&quot;.</em></p>
</div>]]></content:encoded></item><item><title><![CDATA[Working with models in Angular]]></title><description><![CDATA[<div class="kg-card-markdown"><p>One thing I've got pretty used to is using models in Angular; using objects which hold your data may be pretty useful. It makes the developer live significantly easier - so let me show you what I'm talking about and how I handle models in Angular.</p>
<h2 id="theapi">The API</h2>
<p>Let's assume</p></div>]]></description><link>https://nehalist.io/working-with-models-in-angular/</link><guid isPermaLink="false">59abe6e131f3fd289e7faf47</guid><category><![CDATA[angular]]></category><category><![CDATA[javascript]]></category><category><![CDATA[design]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Wed, 06 Sep 2017 21:34:45 GMT</pubDate><media:content url="https://nehalist.io/content/images/2017/09/angular-logo-1.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2017/09/angular-logo-1.png" alt="Working with models in Angular"><p>One thing I've got pretty used to is using models in Angular; using objects which hold your data may be pretty useful. It makes the developer live significantly easier - so let me show you what I'm talking about and how I handle models in Angular.</p>
<h2 id="theapi">The API</h2>
<p>Let's assume we've got an API which returns our users:</p>
<pre><code class="language-rest">GET /api/user

{
    &quot;status&quot;: &quot;success&quot;,
    &quot;response&quot;: [
        {
            &quot;id&quot;: 1,
            &quot;name&quot;: &quot;John&quot;,
            &quot;car&quot;: {
                &quot;brand&quot;: &quot;BMW&quot;,
                &quot;year&quot;: 2015
            }
        },
        {
            &quot;id&quot;: 2,
            &quot;name&quot;: Bob&quot;,
            &quot;car&quot;: {
                &quot;brand&quot;: &quot;Koenigsegg&quot;,
                &quot;year&quot;: 2014
            }
        }
    ]
}
</code></pre>
<h2 id="basicmodels">Basic models</h2>
<p>We're going to create two very simple models; one for <code>User</code> and one for <code>Car</code>.</p>
<p>Our user model:</p>
<pre><code class="language-typescript">// src/app/shared/models/user.model.ts

import {Car} from &quot;./car.model&quot;;

export class User {
  id: number;
  name: string;
  car: Car;
}
</code></pre>
<p>And the car model:</p>
<pre><code class="language-typescript">// src/app/shared/models/car.model.ts

export class Car {
  brand: string;
  year: number;
}
</code></pre>
<p>These two objects will hold our data from the API. We're going to extend these models later, first let's create a service for getting our users:</p>
<pre><code class="language-typescript">// src/app/core/service/user.service.ts

import {Injectable} from &quot;@angular/core&quot;;
import {Http, Response} from &quot;@angular/http&quot;;
import 'rxjs/add/operator/map';
import {User} from &quot;../../shared/models/user.model&quot;;

@Injectable()
export class UserService {
  constructor(private http: Http) {}

  getUser() {
    return this.http.get('/api/user')
      .map((res: Response) =&gt; res.json().response);
  }
}
</code></pre>
<p>Calling <code>getUser()</code> now results in:</p>
<pre><code class="language-rest">(2) [Object, Object]
[
  { id: 1, name: &quot;John&quot;, car: Object },
  { id: 2, name: &quot;Bob&quot;, car: Object }
]
</code></pre>
<p>But that's not exactly what we wanted. We want to get an array of User objects from our service. Let's do this.</p>
<h2 id="deserialization">Deserialization</h2>
<p>We want to deserialize our JSON to our objects. Let's create an interface which provides an API for deserialization:</p>
<pre><code class="language-typescript">// src/app/shared/models/deserializable.model.ts

export interface Deserializable {
  deserialize(input: any): this;
}
</code></pre>
<p>Now we can extend our models and implement our interface. Let's start with the <code>User</code> model:</p>
<pre><code class="language-typescript">// src/app/shared/models/user.model.ts

import {Car} from &quot;./car.model&quot;;
import {Deserializable} from &quot;./deserializable.model&quot;;

export class User implements Deserializable {
  id: number;
  name: string;
  car: Car;

  deserialize(input: any) {
    Object.assign(this, input);
    return this;
  }
}
</code></pre>
<p>The interesting part here is the <code>deserialize</code> method. Basically we're just assigning the input object to <code>this</code> - or, in other words, we're merging the <code>input</code> object with the <code>User</code> object.</p>
<p>But there's still one minor issue here: the <code>car</code> member won't be an instance of <code>Car</code> but still be an Object. We need to tell our <code>deserialize</code> method this manually:</p>
<pre><code class="language-typescript">deserialize(input: any): User {
  Object.assign(this, input);
  this.car = new Car().deserialize(input.car);
  return this;
}
</code></pre>
<p>And, of course, we now need to implement our <code>Deserializable</code> interface for <code>Car</code> too:</p>
<pre><code class="language-typescript">// src/app/shared/models/car.model.ts

import {Deserializable} from &quot;./deserializable.model&quot;;

export class Car implements Deserializable {
  brand: string;
  year: number;

  deserialize(input: any): this {
    Object.assign(this, input);
    return this;
  }
}
</code></pre>
<p>Now we can go back to our service and tell it what we want to get: we want to get an array of <code>User</code>, not just objects:</p>
<pre><code class="language-typescript">// src/app/core/service/user.service.ts

getUser(): Observable&lt;User[]&gt; {
  return this.http.get('/api/user')
    .map((res: Response) =&gt; res.json().response.map((user: User) =&gt; new User().deserialize(user)));
}
</code></pre>
<p>Calling <code>getUser</code> now results in:</p>
<pre><code class="language-rest">(2) [User, User]
[
  User { id: 1, name: &quot;John&quot;, car: Car { brand: &quot;BMW&quot;, year: 2015 } },
  User { id: 2, name: &quot;Bob&quot;, car: Car { brand: &quot;Koenigsegg&quot;, year: 2014 } }
]
</code></pre>
<p>Which is exactly what we wanted. <em>Yay!</em></p>
<h2 id="butwhydowewantthat">But why do we want that?</h2>
<p>Handling raw JSON objects is really painful and hard to maintain. Having &quot;real&quot; entity objects which store data has obvious advantages (maintaining and extensibility) - an example:</p>
<p>Users have a <code>firstName</code> and a <code>lastName</code>. If you're handling the raw JSON you'll have to print out the full name of your user within your templates like this:</p>
<pre><code class="language-html">&lt;ul&gt;
  &lt;li *ngFor=&quot;let user of users&quot;&gt;{{ user.firstName }} {{ user.lastName }}&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>One day your customer calls and tells that the order of first- and lastname should be switched. An endless joy which can be done by a (<em>skilled</em>) potato, since all you need to do is to go through every template and switch the expressions.</p>
<p>But if your <code>user</code> is a <code>User</code> object, you can simply implement a function to print the fullname:</p>
<pre><code class="language-typescript">getFullName() {
  return this.firstName + ' ' + this.lastName;
}

// Just another example, assuming our Car class does implement a `isSportsCar` method
hasSportsCar() {
  return this.car.isSportsCar();
}
</code></pre>
<p>You can now simply call this function in your template:</p>
<pre><code class="language-html">&lt;ul&gt;
  &lt;li *ngFor=&quot;let user of users&quot;&gt;{{ user.getFullName() }}&lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>And whenever a change is required you need to change one single line. Simple, but effective.</p>
<p>Another good reason for using models like this is that we're working with <strong>Type</strong>script. We want to know the type of things when we use them and not just define everything as <code>any</code>. In combination with a good IDE (<em>and you definitely should use a good IDE</em>) this makes life a lot easier.</p>
<p>Of course this can be used for handling forms too:</p>
<pre><code class="language-typescript">form: FormGroup;

createForm() {
  this.form = this.fb.group({
    id: null,
    name: ['', Validators.required],
    car: null
  });
}

private prepareSave(): User {
  return new User().deserialize(this.form.value);
}

onSubmit() {
  const user = this.prepareSave(); // `user` is now an instance of &quot;User&quot;
  // this.http.post('/api/user', user)...
}
</code></pre>
<h2 id="changelog">Changelog</h2>
<h4 id="12052018">12.05.2018</h4>
<ul>
<li>Changed the <code>Deserializable</code> interface from <code>Deserializable&lt;T&gt;</code> to <code>Deserializable</code>. There's no reason for it to be generic.</li>
</ul>
</div>]]></content:encoded></item><item><title><![CDATA[Uploading files in Angular (2/4) to a REST api]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I haven't written any Angular(2(/4)(+)(<em>wtf?</em>)) posts so far - but since I've been working with Angular (<em>okay, let's just call it Angular</em>) for some time now let's do so.</p>
<p>An interesting thing about Angular is that uploading files is barely handled by anyone. It's not mentioned in</p></div>]]></description><link>https://nehalist.io/uploading-files-in-angular2/</link><guid isPermaLink="false">599dc6df5787c822589c6f66</guid><category><![CDATA[angular]]></category><category><![CDATA[javascript]]></category><category><![CDATA[rest]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Sat, 02 Sep 2017 18:20:19 GMT</pubDate><media:content url="https://nehalist.io/content/images/2017/09/angular-logo.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2017/09/angular-logo.png" alt="Uploading files in Angular (2/4) to a REST api"><p>I haven't written any Angular(2(/4)(+)(<em>wtf?</em>)) posts so far - but since I've been working with Angular (<em>okay, let's just call it Angular</em>) for some time now let's do so.</p>
<p>An interesting thing about Angular is that uploading files is barely handled by anyone. It's not mentioned in the docs and the first thing you find by using Google is a third party lib, <a href="http://valor-software.com/ng2-file-upload/">ng2-file-upload</a>.</p>
<p>But what I needed was a <em>simple</em> FileInput field within a form, along with other input fields, which can be send to a REST api. Think of updating your profile, including the possibility of updating your avatar.<br>
Speaking in REST this would lead to a payload something like:</p>
<pre><code class="language-rest">POST /api/user
{
    &quot;name&quot;: &quot;Bob the Builder&quot;,
    &quot;avatar&quot;: &lt;... yeah, what's here? ...&gt;
}
</code></pre>
<p>There are actually different solutions for this and I'd like to cover two of them here, since I ended up using both approaches.</p>
<h1 id="prerequisites">Prerequisites</h1>
<p>Before we're diving right into the solutions we're going to need a few things before.</p>
<p>For this example I'll use <a href="https://github.com/angular/angular-cli">Angular CLI</a> (since I haven't had the opportunity to play around with it so far) which currently uses Angular <code>4.2.4</code>. But this should work in Angular <code>2.x.x</code> as well as in other versions.</p>
<p>You can find the entire source code for this entire project <a href="https://github.com/nehalist/angular-rest-upload">at GitHub</a>.</p>
<p>First of all we're going to need a model for our user:</p>
<pre><code class="language-typescript">// src/app/shared/models/User.ts

export class User {
    id: number;
    avatar: string|any;
}
</code></pre>
<p>This object will held our (client-side) user object and will be used in both approaches.</p>
<h1 id="base64encoding">Base64 encoding</h1>
<p>The solution I've used for &quot;smaller&quot; things (like changing an avatar or similar) is to encode the file client-side, send the encoded string to the server and finally decode and save it there.</p>
<p>Let's create a <em>very simple</em> component for this uploading method called <code>Base64UploadComponent</code>.</p>
<p>First of all we're going to need an HTML template:</p>
<pre><code class="language-html">// src/app/base64-upload/base64-upload.component.html

&lt;form [formGroup]=&quot;form&quot; (ngSubmit)=&quot;onSubmit()&quot;&gt;
  &lt;div class=&quot;form-group&quot;&gt;
    &lt;label for=&quot;name&quot;&gt;Name&lt;/label&gt;
    &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;name&quot; placeholder=&quot;Bob&quot; formControlName=&quot;name&quot;&gt;
  &lt;/div&gt;
  &lt;div class=&quot;form-group&quot;&gt;
    &lt;label for=&quot;avatar&quot;&gt;Avatar&lt;/label&gt;
    &lt;input type=&quot;file&quot; id=&quot;avatar&quot; (change)=&quot;onFileChange($event)&quot; #fileInput&gt;
    &lt;button type=&quot;button&quot; class=&quot;btn btn-sm btn-default&quot; (click)=&quot;clearFile()&quot;&gt;clear file&lt;/button&gt;
  &lt;/div&gt;
  &lt;button type=&quot;submit&quot; [disabled]=&quot;form.invalid || loading&quot; class=&quot;btn btn-success&quot;&gt;Submit &lt;i class=&quot;fa fa-spinner fa-spin fa-fw&quot; *ngIf=&quot;loading&quot;&gt;&lt;/i&gt;&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<p>There's no magic in this file, but if you haven't read the article about <a href="https://angular.io/guide/reactive-forms">Reactive Forms</a> you should probably do that before. The really interesting part here is our file input:</p>
<pre><code class="language-html">&lt;input type=&quot;file&quot; id=&quot;avatar&quot; (change)=&quot;onFileChange($event)&quot; #fileInput&gt;
</code></pre>
<p>We're attaching a change listener here (<code>onFileChange</code>) here which will handle what happens if you select a file to upload. This is actually a really simple function:</p>
<pre><code class="language-typescript">  onFileChange(event) {
    let reader = new FileReader();
    if(event.target.files &amp;&amp; event.target.files.length &gt; 0) {
      let file = event.target.files[0];
      reader.readAsDataURL(file);
      reader.onload = () =&gt; {
        this.form.get('avatar').setValue({
          filename: file.name,
          filetype: file.type,
          value: reader.result.split(',')[1]
        })
      };
    }
  }
</code></pre>
<p>The <a href="https://developer.mozilla.org/en/docs/Web/API/FileReader"><code>FileReader</code></a> is responsible for reading our file contents. As soon we've selected a file we're setting our form value for our <code>avatar</code> to an object which contains the filename, the filetype and the value (which is the base64 encoded string!).</p>
<p>And, well, that's it. When submitting our form our <code>avatar</code> form control now helds the information about the avatar, which can be decoded and saved on our backend.</p>
<h3 id="theentirecomponent">The entire component</h3>
<p>For simplicity here's the entire component:</p>
<pre><code class="language-typescript">// src/app/formdata-upload/base64-upload.component.ts

import {Component, ElementRef, ViewChild} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from &quot;@angular/forms&quot;;

@Component({
  selector: 'base64-upload',
  templateUrl: './base64-upload.component.html'
})
export class Base64UploadComponent {
  form: FormGroup;
  loading: boolean = false;

  @ViewChild('fileInput') fileInput: ElementRef;

  constructor(private fb: FormBuilder) {
    this.createForm();
  }

  createForm() {
    this.form = this.fb.group({
      name: ['', Validators.required],
      avatar: null
    });
  }

  onFileChange(event) {
    let reader = new FileReader();
    if(event.target.files &amp;&amp; event.target.files.length &gt; 0) {
      let file = event.target.files[0];
      reader.readAsDataURL(file);
      reader.onload = () =&gt; {
        this.form.get('avatar').setValue({
          filename: file.name,
          filetype: file.type,
          value: reader.result.split(',')[1]
        })
      };
    }
  }

  onSubmit() {
    const formModel = this.form.value;
    this.loading = true;
    // In a real-world app you'd have a http request / service call here like
    // this.http.post('apiUrl', formModel)
    setTimeout(() =&gt; {
      console.log(formModel);
      alert('done!');
      this.loading = false;
    }, 1000);
  }

  clearFile() {
    this.form.get('avatar').setValue(null);
    this.fileInput.nativeElement.value = '';
  }
}
</code></pre>
<h3 id="finalpayload">Final payload</h3>
<p>Our payload (aka the <code>formModel</code>) should now look something like this:</p>
<pre><code class="language-rest">{
  name: &quot;John&quot;,
  avatar: {
    filename: &quot;10x10png&quot;,
    filetype: &quot;image/png&quot;,
    value: &quot;iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKBAMAAAB/HNKOAAAAGFBMVEXMzMyWlpajo6O3t7fFxcWcnJyxsbG+vr50Rsl6AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAJklEQVQImWNgwADKDAwsAQyuDAzMAgyMbOYMAgyuLApAUhnMRgIANvcCBwsFJwYAAAAASUVORK5CYII=&quot;
  }
}
</code></pre>
<h3 id="savingfileswithphp">Saving files (with PHP)</h3>
<p>In case you're using PHP you'll need something like this to save the file on your server:</p>
<pre><code class="language-php">file_put_contents($payload['avatar']['filename'], base64_decode($payload['avatar']['value']));
</code></pre>
<h3 id="downsides">Downsides</h3>
<p>This approach has one downside: the payload gets bigger. Depending on the image it can get <em>really big</em>. There's an interesting article by David Calhoun about <a href="http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to/">when to Base64 encode images (and when not to)</a>.</p>
<h1 id="usingformdata">Using FormData</h1>
<p>Another approach is using <a href="https://developer.mozilla.org/en/docs/Web/API/FormData">FormData</a>. This makes it possible to send binaries - which is good. But it's slightly more awkward to implement as you'll see.</p>
<p>For this we're creating a <code>FormdataUploadComponent</code> which uses the exact same template as above:</p>
<pre><code class="language-html">// src/app/formdata-upload/formdata-upload.component.html

&lt;form [formGroup]=&quot;form&quot; (ngSubmit)=&quot;onSubmit()&quot;&gt;
  &lt;div class=&quot;form-group&quot;&gt;
    &lt;label for=&quot;name&quot;&gt;Name&lt;/label&gt;
    &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;name&quot; placeholder=&quot;Bob&quot; formControlName=&quot;name&quot;&gt;
  &lt;/div&gt;
  &lt;div class=&quot;form-group&quot;&gt;
    &lt;label for=&quot;avatar&quot;&gt;Avatar&lt;/label&gt;
    &lt;input type=&quot;file&quot; id=&quot;avatar&quot; (change)=&quot;onFileChange($event)&quot; #fileInput&gt;
    &lt;button type=&quot;button&quot; class=&quot;btn btn-sm btn-default&quot; (click)=&quot;clearFile()&quot;&gt;clear file&lt;/button&gt;
  &lt;/div&gt;
  &lt;button type=&quot;submit&quot; [disabled]=&quot;form.invalid || loading&quot; class=&quot;btn btn-success&quot;&gt;Submit &lt;i class=&quot;fa fa-spinner fa-spin fa-fw&quot; *ngIf=&quot;loading&quot;&gt;&lt;/i&gt;&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<p>Our <code>change</code> listener is now slightly different:</p>
<pre><code class="language-typescript">  onFileChange(event) {
    if(event.target.files.length &gt; 0) {
      let file = event.target.files[0];
      this.form.get('avatar').setValue(file);
    }
  }
</code></pre>
<p>We're just assigning the value of the uploaded file to our <code>avatar</code> form value here. But before sending our form we need to create a <code>FormData</code> instance of our form which will be send to our server:</p>
<pre><code class="language-typescript">  private prepareSave(): any {
    let input = new FormData();
    // This can be done a lot prettier; for example automatically assigning values by looping through `this.form.controls`, but we'll keep it as simple as possible here
    input.append('name', this.form.get('name').value);
    input.append('avatar', this.form.get('avatar').value);
    return input;
  }

  onSubmit() {
    const formModel = this.prepareSave();
    this.loading = true;
    // In a real-world app you'd have a http request / service call here like
    // this.http.post('apiUrl', formModel)
    setTimeout(() =&gt; {
      // FormData cannot be inspected (see &quot;Key difference&quot;), hence no need to log it here
      alert('done!');
      this.loading = false;
    }, 1000);
  }
</code></pre>
<p>And... done!</p>
<h3 id="theentirecomponent">The entire component</h3>
<p>Again, here's the entire component:</p>
<pre><code class="language-typescript">// src/app/formdata-upload/formdata-upload.component.ts

import {Component, ElementRef, ViewChild} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from &quot;@angular/forms&quot;;

@Component({
  selector: 'formdata-upload',
  templateUrl: './formdata-upload.component.html'
})
export class FormdataUploadComponent {
  form: FormGroup;
  loading: boolean = false;

  @ViewChild('fileInput') fileInput: ElementRef;

  constructor(private fb: FormBuilder) {
    this.createForm();
  }

  createForm() {
    this.form = this.fb.group({
      name: ['', Validators.required],
      avatar: null
    });
  }

  onFileChange(event) {
    if(event.target.files.length &gt; 0) {
      let file = event.target.files[0];
      this.form.get('avatar').setValue(file);
    }
  }

  private prepareSave(): any {
    let input = new FormData();
    input.append('name', this.form.get('name').value);
    input.append('avatar', this.form.get('avatar').value);
    return input;
  }

  onSubmit() {
    const formModel = this.prepareSave();
    this.loading = true;
    // In a real-world app you'd have a http request / service call here like
    // this.http.post('apiUrl', formModel)
    setTimeout(() =&gt; {
      // FormData cannot be inspected (see &quot;Key difference&quot;), hence no need to log it here
      alert('done!');
      this.loading = false;
    }, 1000);
  }

  clearFile() {
    this.form.get('avatar').setValue(null);
    this.fileInput.nativeElement.value = '';
  }
}
</code></pre>
<h3 id="keydifference">Key difference</h3>
<p>Keep in mind that with this method our form is now part of our request and no longer part of our content. Speaking in PHP again (more specifically in Symfonys <a href="http://api.symfony.com/3.1/Symfony/Component/HttpFoundation/Request.html">HttpFoundation\Request</a> (which is also part of Laravel)) this would mean that the values for our form are now accessed by</p>
<pre><code class="language-php">$avatar = $request-&gt;request-&gt;get('avatar');
</code></pre>
<p>instead of</p>
<pre><code class="language-php">$avatar = $request-&gt;getContent()['avatar'];
</code></pre>
<p>Main advantage of this method is that the file is send as binary, which saves a lot of space.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Installing Ghost 1.0 (without ghost-cli)]]></title><description><![CDATA[<div class="kg-card-markdown"><p>As you may have noticed things are looking slightly different here. That's because I upgraded <a href="https://ghost.org/">Ghost</a> to version <code>1.0</code>. Really cool version, I <em>love</em> the new editor!</p>
<p>One problem with the update was the <a href="https://docs.ghost.org/v1.0.0/docs/install">installation</a>. Everything related to <a href="https://nehalist.io/installing-ghost-1-0-without-ghost-cli/nehalist.io">nehalist.io</a> is hosted on <a href="https://uberspace.de/">Uberspace</a> - a great hoster. But</p></div>]]></description><link>https://nehalist.io/installing-ghost-1-0-without-ghost-cli/</link><guid isPermaLink="false">597a42cd97d1ed440e1e962c</guid><category><![CDATA[Ghost]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Fri, 28 Jul 2017 10:06:58 GMT</pubDate><media:content url="https://nehalist.io/content/images/2017/07/ghost-logo.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://nehalist.io/content/images/2017/07/ghost-logo.png" alt="Installing Ghost 1.0 (without ghost-cli)"><p>As you may have noticed things are looking slightly different here. That's because I upgraded <a href="https://ghost.org/">Ghost</a> to version <code>1.0</code>. Really cool version, I <em>love</em> the new editor!</p>
<p>One problem with the update was the <a href="https://docs.ghost.org/v1.0.0/docs/install">installation</a>. Everything related to <a href="https://nehalist.io/installing-ghost-1-0-without-ghost-cli/nehalist.io">nehalist.io</a> is hosted on <a href="https://uberspace.de/">Uberspace</a> - a great hoster. But sadly you can't simply run the Ghost CLI command <code>ghost install</code> and everything works. You run into problems with permissions, you are <em>no</em> root, etc.. It's a shared hoster - I get the point of not being able to <code>sudo</code> commands :)...</p>
<p>Installing Ghost 1.0 without Ghost CLI is interestingly slightly more complicated than I thought it'd be (<em>probably because I've built the thing myself at first...</em>), but still no magic. In case you're running into problems with Ghost CLI just follow the steps below and you should be good.</p>
<h3 id="differentmethodinstallingghostasnpmmodule">Different method: installing Ghost as NPM module</h3>
<p>Regarding the <a href="https://docs.ghost.org/v1/docs/using-ghost-as-an-npm-module">official docs</a> it's possible to install Ghost as a NPM module, which makes updating way easier than the method below. Detailed instructions on how to do that can be found on the <a href="https://blog.stickleback.dk/ghost-without-the-cli/">Stickleback blog</a> (<em>thanks to Tom Risager for this information!</em>).</p>
<p><strong>Important note</strong>: There's a <a href="https://github.com/TryGhost/Ghost/issues/8795">bug</a> with paths when installing Ghost as npm module; Ghost doesn't use the process directory for finding the content directory specified within the <code>config.&lt;environment&gt;.json</code> and instead uses the Ghost installation directory. That means that the <code>content</code> directory is set to <code>node_modules/ghost/content/</code>, which doesn't make a lot of sense.</p>
<p>As long as this hasn't been officially fixed, a simple workaround is to remove the trailing slash from the <code>contentPath</code> entry in your configuration (hence from <code>contentPath: &quot;content/&quot;</code> to <code>contentPath: &quot;content&quot;</code>). Ghost no longer uses the path as relative path and uses the correct <code>content</code> directory within your ghost installation.</p>
<h3 id="0migrate">0. Migrate</h3>
<p>In case you want to migrate from a previous installation just follow the <a href="https://docs.ghost.org/docs/migrating-to-ghost-1-0-0">official guide</a> on how to do that.</p>
<h3 id="1installyarn">1. Install <code>yarn</code></h3>
<p>You actually don't <em>need</em> Yarn, but since Ghost provides a <code>yarn.lock</code> file it might be a good idea to make use of it. Also, generally speaking <a href="https://www.sitepoint.com/yarn-vs-npm/">yarn is just better than npm</a>:</p>
<pre><code>curl -o- -L https://yarnpkg.com/install.sh | bash
</code></pre>
<h3 id="2downloadthezip">2. Download the zip</h3>
<p>Initially I just cloned the repo and built the thing myself - don't do that.  Just download the latest version, it already includes the built version:</p>
<pre><code>curl -L https://ghost.org/zip/ghost-latest.zip -o ghost-latest.zip
</code></pre>
<p>And extract the thing wherever you want to, e.g.:</p>
<pre><code>unzip ghost-latest.zip -d ghost &amp;&amp; cd ghost
</code></pre>
<h3 id="3installdependencies">3. Install dependencies</h3>
<p><code>cd</code> into the directory where you've unzipped Ghost and run</p>
<pre><code>yarn install
</code></pre>
<p>to install all dependencies.</p>
<h3 id="4configuration">4. Configuration</h3>
<p>Since we're not using Ghost CLI we need to create the configuration file manually. Gladly there are some predefined environment configurations available within the ghost directory, hence we can simply copy them (into the root directory of the Ghost installation):</p>
<pre><code>cp core/server/config/env/config.production.json config.production.json
</code></pre>
<p>Edit the <code>config.production.json</code> to your needs (especially the <code>database</code> settings). Additionally you need to specify the URL and server settings within your configuration file; in the end your file should look something like this:</p>
<pre><code>{
    &quot;url&quot;: &quot;&lt;URL_OF_YOUR_BLOG&gt;&quot;,
    &quot;server&quot;: {
        &quot;host&quot;: &quot;127.0.0.1&quot;,
        &quot;port&quot;: &lt;DESIRED_PORT&gt;
    },
    &quot;database&quot;: {
        &quot;client&quot;: &quot;mysql&quot;,
        &quot;connection&quot;: {
            &quot;host&quot;     : &quot;127.0.0.1&quot;,
            &quot;user&quot;     : &quot;&lt;DB_USER&gt;&quot;,
            &quot;password&quot; : &quot;&lt;DB_PASSWORD&gt;&quot;,
            &quot;database&quot; : &quot;&lt;DB_NAME&gt;&quot;
        }
    },
    &quot;auth&quot;: {
        &quot;type&quot;: &quot;password&quot;
    },
    &quot;paths&quot;: {
        &quot;contentPath&quot;: &quot;content/&quot;
    },
    &quot;logging&quot;: {
        &quot;level&quot;: &quot;info&quot;,
        &quot;rotation&quot;: {
            &quot;enabled&quot;: true
        },
        &quot;transports&quot;: [&quot;file&quot;, &quot;stdout&quot;]
    }
}
</code></pre>
<h3 id="5knexmigrator">5. Knex migrator</h3>
<p>Ghost uses a tool namend &quot;Knex migrator&quot; for database migrations. You first need to install it:</p>
<pre><code>npm install -g knex-migrator
</code></pre>
<p>After that run</p>
<pre><code>NODE_ENV=production knex-migrator init
</code></pre>
<p>This will create all the tables you need for Ghost within your database.</p>
<h3 id="6done">6. Done</h3>
<p>That's it. You can now start Ghost with</p>
<pre><code>NODE_ENV=production node index.js
</code></pre>
<p>Not using Ghost CLI has probably its downsides, but in case you can't simply run it this might be one solution to get Ghost <code>1.0</code> working.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Switching from Windows to Linux]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Since I'm using computers I've always been on Windows for most of the time. The only real exception so far is OS X on my MacBook - but I'm not really a &quot;heavy OS X&quot; user, it just looks good and it always felt kinda wrong for me</p></div>]]></description><link>https://nehalist.io/switching-from-windows-to-linux/</link><guid isPermaLink="false">597a40c9f7965f44f351ecf1</guid><category><![CDATA[General]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Wed, 19 Jul 2017 19:13:38 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Since I'm using computers I've always been on Windows for most of the time. The only real exception so far is OS X on my MacBook - but I'm not really a &quot;heavy OS X&quot; user, it just looks good and it always felt kinda wrong for me to remove OS X from a MacBook (I'm always crying a bit inside when seeing iMacs with Windows). Some years ago I used CentOS on my server, but that was just a little playground to get in touch with server configuration under Linux.</p>
<p>To summarize my OS-experience so far: I'm not biased with &quot;the one real operating system&quot;. I do like Windows (even though I don't like its look since Win8), I do like OS X and I do like the Linux distributions I know (<em>it's hard to tell if I like the ones I don't know</em>). All of them have advantages and disadvantages - since I'm open for all of them I'm not going to write about &quot;what OS you should use&quot;... Use the one you need and like. It's actually that simple.</p>
<p>Speaking of &quot;the one you need&quot;; I switched from Windows to Linux on my home computer. Not entirely - there's still a Windows partition in my system. But when it comes to software development I'm going for Linux from now on.</p>
<p>I used to use <a href="https://www.cygwin.com/">cygwin</a> for some years; the Windows terminal is still a pretty retarded tool and as of now (web-)development is a lot easier with a better terminal.</p>
<p>Some time ago Microsoft introduced <a href="https://msdn.microsoft.com/en-us/commandline/wsl/about">&quot;Ubuntu Bash on Windows&quot;</a> - a way of having <em>&quot;a real&quot;</em> Ubuntu terminal in Windows. I tried it out - it's actually pretty cool, hence I've had completely switched to the Ubuntu Bash on Windows from Cygwin. But to be honest I realized how weird everything got at some point: I worked on Windows, but used mostly Linux stuff. My entire Apache server ran in the &quot;Ubuntu subsystem of Windows&quot;. So my work consisted of the following tools:</p>
<ul>
<li>my IDE</li>
<li>one or more Chrome windows</li>
<li>the Ubuntu bash with <a href="https://github.com/tmux/tmux/wiki">tmux</a> to split my terminal in multiple panels</li>
<li>one cygwin terminal in case of problems</li>
</ul>
<p>At some point I asked myself, <em>&quot;Why are you still working under Windows?&quot;</em>. After some time I realized that I've got no real answer to this question and came to the conclusion: switching to Linux would actually make sense. No more need for having a &quot;ubuntu subsystem&quot; or cygwin. Everything would be &quot;more natural&quot; and way less &quot;hacky&quot;.</p>
<p>So the only remaining question was: which distribution should I take? So I took a look at Ubuntu and Mint - and ultimately went for Mint, because it looks super cool and everything is pretty smooth. To be honest the choice completely went down on look and haptics and nothing else.</p>
<p>Utilizing Linux has become way easier within the last years - so getting all the things I needed to run properly was a fairly easy task. To name some of the things: Apache, mySQL, PHP, Node, Yarn, etc.. Pretty much the things you need for web development. And, one of the MVPs, <a href="https://github.com/tmux/tmux/wiki">tmux</a>!</p>
<p>So, how is it doing so far?</p>
<p>Simply <em>great</em>. My build processes are way faster in this &quot;natural environment&quot; (from 3 - 4 seconds to &lt; 1 second), Apache and mySQL is WAY faster, it doesn't feel hacky or something like this and it's a breeze to work on it.</p>
<p>To come to a conclusion; if you're unsure about to switch to Linux:</p>
<iframe width="500" height="315" src="https://www.youtube.com/embed/ZXsQAXx_ao0" frameborder="0" allowfullscreen></iframe>
<p>Handling Linux has become a lot easier and it's just the better option for web development. I haven't faced any serious downsides so far, and I'm using it in the office and at home. I'll still use my Windows, especially for designing stuff and gaming, but for development Linux just makes more sense.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Logging events to database in Symfony]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I've never written any Symfony posts before, but since I've been using it in my job for some time now it's about time to change that. I really do like Symfony - it's quite refreshing to work with a <em>grown-up</em> framework and leaving the nodejs/javascript scene, where most things</p></div>]]></description><link>https://nehalist.io/logging-events-to-database-in-symfony/</link><guid isPermaLink="false">597a40c9f7965f44f351ecee</guid><category><![CDATA[PHP]]></category><category><![CDATA[Symfony]]></category><category><![CDATA[Monolog]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Tue, 24 Jan 2017 22:09:28 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I've never written any Symfony posts before, but since I've been using it in my job for some time now it's about time to change that. I really do like Symfony - it's quite refreshing to work with a <em>grown-up</em> framework and leaving the nodejs/javascript scene, where most things are still pretty <em>young</em> and partially even immature, apart for some time.</p>
<p>One of my most recent tasks was to implement a logging system for specific events, mostly related to entities (e.g. events like adding a product, etc.). Since it should be easy to search specific log entries everything is going to land within a database.</p>
<p>We're going through three different stages in this post:</p>
<ol>
<li>Logging to database in Symfony using Monolog by writing our own handler</li>
<li>Add extra information by using a processor</li>
<li>How to handle event and implement event subscribers</li>
</ol>
<p>These sections will be handled separately and are mostly independent from each other - hence feel free to jump to whatever you need without having to worry about to miss something important.</p>
<h2 id="1loggingtodatabaseinsymfonyusingmonologbywritingourownhandler">1. Logging to database in Symfony using Monolog by writing our own handler</h2>
<p>Interestingly I didn't find a clean and fast solution for database logging for Symfony. There's a <a href="https://github.com/waza-ari/monolog-mysql">monolog-mysql</a> handler on GitHub - sadly it's <a href="https://github.com/waza-ari/monolog-mysql/issues/12">triggering some errors</a> (not just in Silex, also in Symfony). Luckily Symfony and Monolog make implementing it ourselves quite easy.</p>
<h3 id="theentity">The entity</h3>
<p>The first thing we need is an entity for the log entries.</p>
<pre><code class="language-php">// src/AppBundle/Entity/Log.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=&quot;AppBundle\Repository\LogRepository&quot;)
 * @ORM\Table(name=&quot;log&quot;)
 * @ORM\HasLifecycleCallbacks
 */
class Log
{
    /**
     * @ORM\Id
     * @ORM\Column(type=&quot;integer&quot;)
     * @ORM\GeneratedValue(strategy=&quot;AUTO&quot;)
     */
    private $id;

    /**
     * @ORM\Column(name=&quot;message&quot;, type=&quot;text&quot;)
     */
    private $message;

    /**
     * @ORM\Column(name=&quot;context&quot;, type=&quot;array&quot;)
     */
    private $context;

    /**
     * @ORM\Column(name=&quot;level&quot;, type=&quot;smallint&quot;)
     */
    private $level;

    /**
     * @ORM\Column(name=&quot;level_name&quot;, type=&quot;string&quot;, length=50)
     */
    private $levelName;

    /**
     * @ORM\Column(name=&quot;extra&quot;, type=&quot;array&quot;)
     */
    private $extra;

    /**
     * @ORM\Column(name=&quot;created_at&quot;, type=&quot;datetime&quot;)
     */
    private $createdAt;

    /**
     * @ORM\PrePersist
     */
    public function onPrePersist()
    {
        $this-&gt;createdAt = new \DateTime();
    }
}
</code></pre>
<p><strong>Important</strong>: To keep this piece of code a bit shorter the getters and setters are missing here. Therefore don't forget to run <code>php bin/console doctrine:generate:entities AppBundle/Entity/Log</code> to generate them.</p>
<p>This scheme is basically the one <a href="https://github.com/Seldaek/monolog/blob/master/doc/message-structure.md">used by Monolog</a>, except <code>channel</code>, but since we're using an own channel for database logging it would be same everytime.</p>
<p>To have our <code>createdAt</code> created automatically we're using the <a href="http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-haslifecyclecallbacks"><code>HasLifecycleCallbacks</code></a> annotation in conjunction with the <code>PrePersist</code> annotation to set the date before saving entities.</p>
<h3 id="themonologhandler">The Monolog handler</h3>
<p>The next thing we need is a new handler for Monolog.</p>
<pre><code class="language-php">// src/AppBundle/Util/MonologDBHandler.php

namespace AppBundle\Util;

use AppBundle\Entity\Log;
use Doctrine\ORM\EntityManagerInterface;
use Monolog\Handler\AbstractProcessingHandler;

class MonologDBHandler extends AbstractProcessingHandler
{
    /**
     * @var EntityManagerInterface
     */
    protected $em;

    /**
     * MonologDBHandler constructor.
     * @param EntityManagerInterface $em
     */
    public function __construct(EntityManagerInterface $em)
    {
        parent::__construct();
        $this-&gt;em = $em;
    }

    /**
     * Called when writing to our database
     * @param array $record
     */
    protected function write(array $record)
    {
        $logEntry = new Log();
        $logEntry-&gt;setMessage($record['message']);
        $logEntry-&gt;setLevel($record['level']);
        $logEntry-&gt;setLevelName($record['level_name']);
        $logEntry-&gt;setExtra($record['extra']);
        $logEntry-&gt;setContext($record['context']);
        
        $this-&gt;em-&gt;persist($logEntry);
        $this-&gt;em-&gt;flush();
    }
}
</code></pre>
<p>Pretty simple class; the <code>write</code> method will called everytime we're going to utilize this handler, the constructor is to get the entity manager object, which will be injected in the next step.</p>
<h3 id="configuringmonologandsymfony">Configuring Monolog and Symfony</h3>
<p>First let's configure Monolog by opening the <code>app/config/config.yml</code> and add the following lines:</p>
<pre><code>monolog:
    channels: ['db']
    handlers:
        db:
            channels: ['db']
            type: service
            id: monolog.db_handler
</code></pre>
<p>We now have a custom channel for db logging which is handled by the class defined above. We just need to tell Symfony about the service; open the <code>app/config/services.yml</code> and add these lines:</p>
<pre><code>services:
    # ...

    monolog.db_handler:
        class: AppBundle\Util\MonologDBHandler
        arguments: ['@doctrine.orm.entity_manager']
</code></pre>
<p>Now Symfony knows about the handler and injects our entity manager object.</p>
<h3 id="thatsit">That's it.</h3>
<p>We're done. <em>Wohoo!</em></p>
<p>That's basically everything you need for database logging. Validation, etc. is up to you. To utilize our database logger now just use it as follows:</p>
<pre><code class="language-php">$this-&gt;container-&gt;get('monolog.logger.db')-&gt;info('something happened', [
    'foo' =&gt; 'bar'
]);
</code></pre>
<p>It's used the exact way as <a href="http://symfony.com/doc/current/logging.html">default logging with Monolog</a>.</p>
<h2 id="2addextrainformationbyusingaprocessor">2. Add extra information by using a processor</h2>
<p>The application I was writing required detailed log entries. It's not just enough to know <em>what</em> happened, I also required to know <em>how</em> it happened. Therefor I wanted to save some client and request information for every entry. Thanks to <a href="http://symfony.com/doc/current/logging/processors.html">Processors</a> this is a very simple task:</p>
<pre><code class="language-php">// src/AppBundle/Util/RequestProcessor.php

namespace AppBundle\Util;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Class RequestProcessor
 * @package AppBundle\Util
 */
class RequestProcessor
{
    /**
     * @var RequestStack
     */
    protected $request;

    /**
     * RequestProcessor constructor.
     * @param RequestStack $request
     * @param ContainerInterface $container
     */
    public function __construct(RequestStack $request)
    {
        $this-&gt;request = $request;
    }

    /**
     * @param array $record
     * @return array
     */
    public function processRecord(array $record)
    {
        $req = $this-&gt;request-&gt;getCurrentRequest();
        $record['extra']['client_ip']       = $req-&gt;getClientIp();
        $record['extra']['client_port']     = $req-&gt;getPort();
        $record['extra']['uri']             = $req-&gt;getUri();
        $record['extra']['query_string']    = $req-&gt;getQueryString();
        $record['extra']['method']          = $req-&gt;getMethod();
        $record['extra']['request']         = $req-&gt;request-&gt;all();

        return $record;
    }
}
</code></pre>
<p>And add it to your <code>app/config/services.yml</code>:</p>
<pre><code>services:
    monolog.processor.request:
        class: AppBundle\Util\RequestProcessor
        arguments: ['@request_stack', '@service_container']
        tags:
            - { name: monolog.processor, method: processRecord, handler: db }
</code></pre>
<p>Now every time we log through our <code>db</code> channel this processor will add additional information to every single log entry. It's up to you to add whatever data you want (tokens, user information, ...).</p>
<h2 id="3howtohandleeventandimplementeventsubscribers">3. How to handle event and implement event subscribers</h2>
<p>The last thing I needed to think of was <em>where</em> to log things. My initial attempt (<em>keep in mind that the application I used all these techniques was/is my second Symfony project</em>) was to put all logging into the controllers, but that just didn't felt right.</p>
<p>To keep everything <a href="https://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> and organize it better I utilized the <a href="http://symfony.com/doc/current/components/event_dispatcher.html">event system</a> and implemented a fairly easy logic: everytime something happens which should be logged an event is fired (e.g. <code>product_added</code>). Event subscribers are listening for these events and handle the logging.</p>
<p>The Symfony docs suggests events for every operation (like the <code>OrderPlacedEvent</code> there'd probably be a <code>OrderDeletedEvent</code> and <code>OrderUpdatedEvent</code>) - since most of my events are simply logging entities to the database I needed to break that down a bit and generalize it more. I ended up using more general events, in terms of orders it would be something like <code>OrderEvents</code>. These events look like this:</p>
<pre><code class="language-php">// src/AppBundle/Events/OrderEvent.php

&lt;?php
namespace AppBundle\Events;

/**
 * Class OrderEvent
 * @package AppBundle\Events
 */
class OrderEvent extends AbstractEvent
{
    const ORDER_ADDED   = 'order_added';
    const ORDER_UPDATED = 'order_updated';
    const ORDER_DELETED = 'order_deleted';
}
</code></pre>
<p>Very simple class which provides names for all the actions an order event can have. A bit more interesting is the parent class <code>AbstractEvent</code>:</p>
<pre><code class="language-php">// src/AppBundle/Events/AbstractEvent.php

namespace AppBundle\Events;

use Symfony\Component\EventDispatcher\Event;

/**
 * Class AbstractEvent
 * @package AppBundle\Events
 */
abstract class AbstractEvent extends Event
{
    /**
     * @var null
     */
    protected $entity;

    /**
     * AbstractEvent constructor.
     * @param null $entity
     */
    public function __construct($entity = null)
    {
        $this-&gt;entity = $entity;
    }

    /**
     * @return bool|null
     */
    public function getEntity()
    {
        if($this-&gt;entity != null) {
            return $this-&gt;entity;
        }
        return false;
    }
}
</code></pre>
<p>Every time we create a new event instance we can pass an entity and get this entity from outside. This is basically the <code>OrderPlacedEvent</code> class from the Symfony docs in a way more generic way.</p>
<p><em>Note:</em> It would be good to have some kind of type validation here, since it'd make sense to have an <code>OrderEvent</code> just accepting an <code>Order</code> entity. Sadly, I'm not sure yet about how to implement that.</p>
<p>The next thing we need is an event subscriber which listens for specific events. Let's assume our listener is listening for some <code>OrderEvent</code>:</p>
<pre><code class="language-php">// src/AppBundle/EventSubscriber/OrderSubscriber.php

namespace AppBundle\EventSubscriber;

use AppBundle\Events\OrderEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Class OrderSubscriber
 * @package AppBundle\EventSubscriber
 */
class OrderSubscriber extends AbstractSubscriber implements EventSubscriberInterface
{
    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            OrderEvent::ORDER_ADDED    =&gt; 'onOrderAdded',
            OrderEvent::ORDER_UPDATED  =&gt; 'onOrderUpdated',
            OrderEvent::ORDER_DELETED  =&gt; 'onOrderDeleted'
        ];
    }

    /**
     * @param OrderEvent $event
     */
    public function onOrderAdded(OrderEvent $event)
    {
        $this-&gt;logEntity(OrderEvent::ORDER_ADDED, [
            'product' =&gt; $event-&gt;getEntity()-&gt;getProduct()
        ]);
    }

    /**
     * @param OrderEvent $event
     */
    public function onOrderUpdated(OrderEvent $event)
    {
        $this-&gt;logEntity(OrderEvent::ORDER_UPDATED, [
            'product' =&gt; $event-&gt;getEntity()-&gt;getProduct()
        ]);
    }

    /**
     * @param OrderEvent $event
     */
    public function onOrderDeleted(OrderEvent $event)
    {
        $this-&gt;logEntity(OrderEvent::ORDER_DELETED, [
            'product' =&gt; $event-&gt;getEntity()-&gt;getProduct()
        ]);
    }
}
</code></pre>
<p>Our subscriber now handles logging to the database. Again I used a parent class for some general logic, the <code>AbstractSubscriber</code>:</p>
<pre><code class="language-php">// src/AppBundle/EventSubscriber/AbstractSubscriber.php

namespace AppBundle\EventSubscriber;

use Symfony\Component\DependencyInjection\ContainerInterface;

/*
 * Class AbstractSubscriber
 * @package AppBundle\EventSubscriber
*/
abstract class AbstractSubscriber
{
    /**
     * Default action for logs
     */
    const UNKNOWN_ACTION = 'unknown_action';
    
    /**
     * @var ContainerInterface
     */
    protected $container;
    
    /**
     * AbstractSubscriber constructor.
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this-&gt;container = $container;
    }
    
    /**
     * @param string $action
     * @param array $entityFields
     */
    protected function logEntity($action = self::UNKNOWN_ACTION, array $entityFields)
    {
        $this-&gt;container-&gt;get('monolog.logger.db')-&gt;info($action, [
            'entity' =&gt; $entityFields
        ]);
    }
}
</code></pre>
<p>Since logging entities is the main purpose of this system it makes sense to have a <code>logEntity</code> method which is responsible for writing entity data to the <code>context</code> of our log entry.</p>
<p>The last thing we need to do is to register our subscribers. Add the following lines to the <code>app/config/services.yml</code>:</p>
<pre><code>services:
    # ...

    appbundle.subscriber.abstract_subscriber:
        class: AppBundle\EventSubscriber\AbstractSubscriber
        arguments: ['@service_container']

    appbundle.subscriber.order_subscriber:
        class: AppBundle\EventSubscriber\OrderSubscriber
        parent: appbundle.subscriber.abstract_subscriber
        tags:
            - { name: kernel.event_subscriber }
</code></pre>
<p>We need to register every subscriber here - don't forget about the <code>parent</code> key to inject dependencies to the <code>AbstractSubscriber</code> class.</p>
<h2 id="example">Example</h2>
<p>Dispatching an event is simple as is:</p>
<pre><code>$this-&gt;get('event_dispatcher')-&gt;dispatch(
    OrderEvent::ORDER_ADDED,
    new OrderEvent($order)
);
</code></pre>
<h2 id="finalwords">Final words</h2>
<p>As said within the post: the project I implemented this system is my second Symfony project. I'm sure there's room for improvement, but I'm pretty happy with it so far. Feel free to suggest any improvement or changes in the comments.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Not maintaining my WordPress theme, Gitsta, anymore]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Nearly three years ago I've released my first WordPress theme, called Gitsta, inspired by the GitHub blog. To be honest it got more attention than I'd have thought - more than 600 active installations are pretty okay I guess.</p>
<p>But let me be honest here: I just can't stand the</p></div>]]></description><link>https://nehalist.io/not-maintaining-my-wordpress-theme-gitsta-anymore/</link><guid isPermaLink="false">597a40c9f7965f44f351eced</guid><category><![CDATA[WordPress]]></category><category><![CDATA[Gitsta]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Thu, 05 Jan 2017 10:17:03 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Nearly three years ago I've released my first WordPress theme, called Gitsta, inspired by the GitHub blog. To be honest it got more attention than I'd have thought - more than 600 active installations are pretty okay I guess.</p>
<p>But let me be honest here: I just can't stand the WordPress environment. <em>It drives me completely nuts</em>. I've written a post about <a href="https://nehalist.io/why-im-not-the-biggest-wordpress-fan/">why I actually dislike WordPress</a>, but theme development for the <a href="https://wordpress.org/themes/gitsta/">official theme register</a> is just a pain in the ass.</p>
<p>Before someone now rages and shouts at me for criticizing the (probably worlds biggest) theme archive let me explain that.</p>
<p>Everytime I submitted a theme update the outcome was <a href="https://themes.trac.wordpress.org/ticket/20724">dependent on the reviewer</a>. Things which were absolutely no problem in one version became suddenly the reason for getting rejected in a latter version (e.g. shortcodes). I do understand that requirements do change over time - but they should never be dependend on who's reviewing. Everytime I submitted a new update it was a bit like playing Roulette - you may win, or you don't... It's not that easy to influence.</p>
<p>Another thing which drives me completely insane are the weird rules and requirements you need to match to get approved. Some examples:</p>
<ul>
<li>Loading jQuery over CDN? Nope. Even though there are some <a href="http://stackoverflow.com/questions/2180391/why-should-i-use-googles-cdn-for-jquery">good reasons</a> to do that.</li>
<li>You need to define a variable named <code>$content_width</code>. I still don't know what this thing does - and I don't want to know that.</li>
<li>No minified files.</li>
<li>You need to prefix your variables. Probably because of fear of breaking some <code>global</code> bullshit.</li>
<li>One of the funniest things: since my theme suggested markdown usage it includes a small markdown help guide. Theme got rejected because the &quot;<em>link</em>&quot; syntax linked to my blog - and you're not allowed to link to authors website more than once.</li>
</ul>
<p>I (<em>gladly</em>) haven't submitted that many versions - but I'm sure there are a lot more useless rules which makes you facepalm really hard.</p>
<p>What makes me deciding in not maintaining my theme anymore was the last review. <strong>Five</strong> months ago I submitted a very small change, which changed the theme <a href="https://themes.trac.wordpress.org/ticket/25811">to load jQuery via CDN</a>. It got rejected, but as always I just reverted my change and submitted the theme again... and didn't get an answer for <a href="https://themes.trac.wordpress.org/ticket/34950"><strong>five</strong> months</a>.</p>
<p>All of a sudden I've got an entire new list of requirements I need to fulfil. All I've done was reverted my CDN changes - and then this... And you know what? Screw that.</p>
<p>I like my theme and don't want it to let it die. But one thing's for sure: I will not support nor maintain the WordPress.org-version of it. With that I can get rid of all these weird rules and implement a clean and neat piece of software. It surely will take some time, but it will be way better than the current version of it.</p>
</div>]]></content:encoded></item><item><title><![CDATA[AngularJS with Babel in SailsJS]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Since I've been porting my long-term project <a href="https://nehalist.io/angularjs-with-babel-in-sailsjs/">from CoffeeScript</a> to native JavaScript I thought it'd be a good idea to share how it's working now.</p>
<p>Assuming we've got a brand new SailsJS application, the first thing we need is to install <code>grunt-babel</code> and configure the task.</p>
<pre><code># Install the Grunt task</code></pre></div>]]></description><link>https://nehalist.io/angularjs-with-babel-in-sailsjs/</link><guid isPermaLink="false">597a40c9f7965f44f351ecec</guid><category><![CDATA[javascript]]></category><category><![CDATA[angular]]></category><category><![CDATA[sailsjs]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Sat, 10 Dec 2016 16:27:39 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Since I've been porting my long-term project <a href="https://nehalist.io/angularjs-with-babel-in-sailsjs/">from CoffeeScript</a> to native JavaScript I thought it'd be a good idea to share how it's working now.</p>
<p>Assuming we've got a brand new SailsJS application, the first thing we need is to install <code>grunt-babel</code> and configure the task.</p>
<pre><code># Install the Grunt task
npm i grunt-babel --save-dev
npm i babel-preset-es2015 --save-dev
</code></pre>
<p>Create a new file in <code>tasks/config/</code> called <code>babel.js</code> with the following contents:</p>
<pre><code class="language-javascript"># tasks/config/babel.js

module.exports = function(grunt) {
  grunt.config.set('babel', {
    dev: {
      options: {
        presets: ['es2015']
      },
      files: [{
        expand: true,
        cwd: 'assets/js/',
        src: ['**/*.js', '!dependencies/**/*.js'],
        dest: '.tmp/public/js/',
        ext: '.js'
      }]
    }
  });

  grunt.loadNpmTasks('grunt-babel');
};
</code></pre>
<p>Open <code>tasks/register/compileAssets.js</code> and change <code>coffee:dev</code> to <code>babel:dev</code> (around line ~7).</p>
<p><strong>That's it.</strong><br><br>
You can now use <a href="https://babeljs.io/learn-es2015/">ES2015 JavaScript</a> in your Sails assets. Your &quot;future JavaScript&quot; will be transformed by Babel so that most current browser can handle it.</p>
<h2 id="whataboutangularjs">What about AngularJS?</h2>
<p>Having the features of ES6 makes developing Angular way more comfortable.</p>
<h3 id="controllers">Controllers</h3>
<p>Controllers can easily be implemented through classes now, for example:</p>
<pre><code class="language-javascript">class HelloController {
  constructor() {
    this.message = 'Hello World';
  }
}

awesomeApp
  .controller('HelloController', HelloController);
</code></pre>
<p>While accessing class members like this:</p>
<pre><code>&lt;div ng-controller=&quot;HelloController as HelloCtrl&quot;&gt;
  {{ HelloCtrl.message }}
&lt;/div&gt;
</code></pre>
<p>See <a href="https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y030">here</a> for additional information about why using <code>controller As ctrl</code> and not using <code>$scope</code>.</p>
<h3 id="controllersanddependencyinjection">Controllers and dependency injection</h3>
<p>You may have some dependencies for your controllers. They're automatically injected by Angular, for example:</p>
<pre><code class="language-javascript">class HelloController {
  constructor($element) {
    this.message = 'Hello World';
    console.log($element);
  }
}
</code></pre>
<p>If you want to use your dependencies in other methods of your class simply bind them to <code>this</code>:</p>
<pre><code class="language-javascript">class HelloController {
  constructor($element) {
    this.message = 'Hello World';
    this.$element = $element;

    this.doStuff();
  }

  doStuff() {
    console.log(this.$element);
  }
}
</code></pre>
<p><em>Note: Probably not the most elegant solution. If someone has a better one feel free to tell me.</em></p>
<h3 id="services">Services</h3>
<p>Basically the same as for controllers:</p>
<pre><code class="language-javascript">class GreetingsService {
  greet() {
    console.log('Hello!');
  }
}

awesomeApp
  .factory('GreetingsService ', GreetingsService);
</code></pre>
<p>Used like this:</p>
<pre><code class="language-javascript">class HelloController {
  constructor($element, GreetingsService) {
    this.message = 'Hello World';
    GreetingsService.greet();
  }
}
</code></pre>
<h3 id="directives">Directives</h3>
<p>Even directives are that simple:</p>
<pre><code class="language-javascript">class DoStuff {
  constructor() {
    this.restrict = 'E';
  }

  template() {
    return 'Hey {{name}}';
  }

  link(scope, elem, attrs) {
    scope.name = 'Bob';
  }
}

awesomeApp
  .directive('doStuff', DoStuff);
</code></pre>
</div>]]></content:encoded></item><item><title><![CDATA[A technological misery: my problem with CoffeeScript today]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Quite some time ago I had to decide for some technologies I'd like to use for one of my projects. It's quite a big project - with some fancy requirements like realtime components or being completely RESTified, backend and frontend independent from each other, etc..</p>
<p>I had a look at</p></div>]]></description><link>https://nehalist.io/a-technological-misere-my-problem-with-coffeescript-today/</link><guid isPermaLink="false">597a40c9f7965f44f351eceb</guid><category><![CDATA[javascript]]></category><category><![CDATA[coffeescript]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Tue, 29 Nov 2016 22:29:14 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Quite some time ago I had to decide for some technologies I'd like to use for one of my projects. It's quite a big project - with some fancy requirements like realtime components or being completely RESTified, backend and frontend independent from each other, etc..</p>
<p>I had a look at different technologies; for back- and frontend. I quickly found a neat solution on the server-side: NodeJS. It has good realtime capabilities, is extremely fast (as long as you're not doing math-heavy stuff) and JavaScript is pretty simple.</p>
<p>PHP wouldn't have fit this requirements; doing realtime stuff with PHP is still <em>very</em> hacky. Running infinite loops and polling... that's just <em>really</em> weird.</p>
<p>I've done some things in Java but didn't get used to it - and since most of my experiences were with GWT I'm kinda afraid of doing web stuff with Java.</p>
<p>The next thing I had to find out: which NodeJS framework to use? I could have gone the simple way of just taking <a href="http://expressjs.com/">ExpressJS</a> and putting my API on top... but since I really like MVC I wanted something implementing this pattern.</p>
<p>Sadly (or gladly, I'm not sure yet) the NodeJS world is still very young and there aren't tons of frameworks out there. Back then the only real choice was <a href="http://sailsjs.com/">SailsJS</a>. It implements the MVC pattern, helps in developing realtime application by exposing some realtime stuff and is actively maintained.</p>
<p>I tried different frameworks for the client, for example <a href="https://nehalist.io/ember-so-far/">Ember</a> or <a href="https://nehalist.io/realtime-feed-with-sails-angular-and-socketio/">Angular</a>. Both are great frameworks - but in the end I chose Angular, since I had some experience with it and liked its approach of how things are developed.</p>
<p>Lastly I wanted some OOP - on either backend or frontend (preferably both). Just some classes and some inheritance and I would have been happy.</p>
<p>TypeScript was very young at this point and I didn't know much about Babel. So the only thing left was CoffeeScript. It looked a bit weird (and I really don't like this indent style) but it allowed me to write object oriented - which was everything I asked for!</p>
<p>As the project progressed tons of new technologies were born; if I could go back in time I'd probably wait for a component-based framework like Angular 2 or React. But it was important to stick to my decisions; due to the project size I couldn't afford going back that much by re-implementing the entire client. I'm already very vulnerable to one of the most basic rules of developing:</p>
<blockquote>
<p>Premature optimization is the root of all evil.</p>
</blockquote>
<p>I often catch myself refactoring stuff just because of _&quot;This can be done better!&quot; or <em>&quot;Just a slight change here...! (which most of the time resolves in rewriting entire modules)&quot;</em>. This is <em>bad</em> (well, not really, but it's not economical) - but since it's my private project it is kinda acceptable. (<em>When working for clients and knowing that I could have done some things better - but there's no budget or interest in it - it slowly kills me inside...</em>)</p>
<p>But throughout the months (or even years by now) I've learned to somehow control my urge to go virtually back in time and do things again just because of having it done better. After some time I learned that I want to be done at some point - hence I always need to remember the wisdom from above.</p>
<p>But what if the technology you decided to use is becoming obsolet or - even worse - dying?</p>
<p>That's exactly what is happening to CoffeeScript.</p>
<p>Babel and TypeScript are &quot;more familiar&quot; to write (<em>I like curly braces!</em>), offer the same or even more features (especially TypeScript) and have a huge foundation;</p>
<p>Babel is basically just native JS - but it allows you to use features from future JavaScript standards. This means that at some point in the future the current Babel will be the same as native JS. It's safe to say at this point that this technology won't die in near future.</p>
<p>TypeScript is just a superset of Babel - it adds types (and some more features) to ES6. And what's also pretty important here: Microsoft stands behind it.</p>
<p>In the end using CoffeeScript just because of OOP isn't worth it anymore. If you want to have OOP you can just go with Babel or TypeScript. But is &quot;having alternatives&quot; really a reason not to use a technology? No, of course not. <em>But</em>...</p>
<p>CoffeeScript is dying. Big projects like <a href="https://gitlab.com/gitlab-org/gitlab-ce/issues/20098">GitLab</a> or <a href="https://github.com/electron/electron/pull/4065">Atom</a> are moving away from CoffeeScript. For the same reasons as this post stated: it used to be good, but now there are way better alternatives.</p>
<p>There's no official statement about &quot;CoffeeScript is dead&quot; - but just keep in mind that:</p>
<ol>
<li>as said above: seeing big projects moving away from a technology isn't good for the technology.</li>
<li>it seems like it's already neglected by its creators. <a href="https://github.com/jashkenas/coffeescript/releases">Just 7 releases</a> this year, where four of them were just patches and the other three were minor releases.</li>
</ol>
<p>According to <a href="https://github.com/jashkenas/coffeescript/issues/4288">this</a> issue we might see something like CoffeeScript Version 2 - but I haven't found any decent information about this.</p>
<p>In the end the remaining question is: should I get rid of CoffeeScript and re-implement in ES6 (or TypeScript)? <em>Yes. I'm already migrating to ES6.</em></p>
<p>There's a chance that CoffeeScript might disappear - or gets &quot;forgotten&quot; by its developers. I'm sure that it'll be around for a long time (since it's already used in a lot of projects), but I'm not sure if it's future-proof. Honestly I don't believe this at all. So migrating at this point made sense for me; at this stage of my project migration takes around one day, which is fine.</p>
<p>And migrating has one additional advantage: if someone joins the project he or she could easily start developing. No need to learn a new technology at all.</p>
<p>So let's come to a conclusion:</p>
<ul>
<li>make sure the technologies you're going to use are future-proof as good as you can.</li>
<li>compare your technology. Don't be that silly kid who's like <em>&quot;technology XY is the best!&quot;</em>.</li>
<li>stick to your technologies as good as possible. Don't swap them just because there's something newer or more fancy. Only swap if there's an urgent need (like the technology lost its maintainer, its going to be abadoned, whatever)</li>
<li>and <strong>always</strong> keep in mind that: <em>Premature optimization is the root of all evil.</em></li>
</ul>
<p><em>P.S. I will make use of ES6 or TypeScript in Sails as soon as <code>v1</code> <a href="https://twitter.com/nehalist/status/797137195039592448">is released</a>. Since I'm really interested in this there'll be a post about it for sure.</em></p>
</div>]]></content:encoded></item><item><title><![CDATA[Twenty six]]></title><description><![CDATA[<div class="kg-card-markdown"><p>It's that time again of the year; two days ago was my birthday. <em>Happy birthday, me!</em> Looking back at the last year I can surely say: that was <em>one hell of a shitty</em> year.</p>
<p>To get an idea of what I mean by &quot;shitty&quot;:</p>
<ul>
<li>my cat died. Probably</li></ul></div>]]></description><link>https://nehalist.io/twenty-six/</link><guid isPermaLink="false">597a40c9f7965f44f351ecea</guid><category><![CDATA[Personal]]></category><dc:creator><![CDATA[Kevin]]></dc:creator><pubDate>Sat, 29 Oct 2016 13:29:07 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>It's that time again of the year; two days ago was my birthday. <em>Happy birthday, me!</em> Looking back at the last year I can surely say: that was <em>one hell of a shitty</em> year.</p>
<p>To get an idea of what I mean by &quot;shitty&quot;:</p>
<ul>
<li>my cat died. Probably the worst thing.</li>
<li>I lost a decent amount of money due to a shitty client. (implemented his application, he used it but didn't want to pay it...)</li>
<li>I had <em>seven</em> surgeries throughout one single year.</li>
<li>I spent around one entire month in hospitals, not being able to do anything productive (hard to do so when you can't sit down, lie on your back or walk). It took me nearly one entire year to get well again.</li>
<li>due to not being able to work, I had to sell my car. <em>And I loved my car...</em></li>
<li>since I'm in need of a car I had to buy a new (and way cheaper) one. To keep this simple: the car I bought had an engine damage. The guy who sold me the car did know that, but didn't tell me. Took a lawyer, a lot of time and even more money to withdraw from the purchase contract.</li>
</ul>
<p><img src="http://dearkidlovemom.com/wp-content/uploads/2014/10/but-wait-theres-more.jpg" alt=""></p>
<p>In the end I lost my job too. The actual plan was to return to the company I worked before my sickness kicked in; but - <em>who would have thought about that</em> - that didn't work out well, since the company had no open positions at the time I recovered (around 2 months ago). Now I was officially jobless too, <em>wohoo</em>. (This was also the reason why there have not been any new blog posts for some time)</p>
<p>But things started to turn at some point. I bought a new car (funnily the exact same model as the one with the engine damage), recovered from all the pain and suffering and found a new job.</p>
<p>So, if I had to answer the &quot;what lessons did you learn?&quot; question now, I'd say:</p>
<ul>
<li>cats should live way longer.</li>
<li>blindly trusting anyone is a pretty retarded thing to do.</li>
<li>believing that a small-sized company can keep its word throughout the timeframe of more than 6 months is also not the smartest thing to do.</li>
</ul>
<p>But there's one thing I've learned which is the most important: it doesn't matter how shitty things go, at some point (maybe not until you've reached the bottom end) there'll be a turning point. I didn't know how long it will take or how many surgeries it'll take to get rid of my disease - and not knowing what's going to happen is probably one of the worst feelings. But I was (at least most of the time) certain that it'll be better at some point. And, happily, it turned out to be true. Guess I could say I became a lot more optimistic within this time.</p>
<p>I'm not even completely mad about having such a year (except for my cat). It had taught me a lot of things, it has shown me different perspectives and new ways to look at things.</p>
<p>But, nevertheless, I'm hoping for the next ones to get better. I've gained enough &quot;life experience&quot; for the next few years for my taste ;)...</p>
<p><img src="https://nehalist.io/content/images/2016/10/740107_158535050961765_808301529_o.jpg" alt=""></p>
</div>]]></content:encoded></item></channel></rss>