Nikola Brežnjak blog - Tackling software development with a dose of humor
  • Home
  • Daily Thoughts
  • Ionic
  • Stack Overflow
  • Books
  • About me
Home
Daily Thoughts
Ionic
Stack Overflow
Books
About me
  • Home
  • Daily Thoughts
  • Ionic
  • Stack Overflow
  • Books
  • About me
Nikola Brežnjak blog - Tackling software development with a dose of humor
CodeProject, MEAN

How to add a comment field to MEAN.js Article example

MEAN_Grunt_604x270

If you happen to like the image above, and you’re thinking to yourself how cool it would look like as a sticker, take a look at a few that I made.

TL;DR

In my previous tutorial about the MEAN stack, I showed you how to get your MEAN stack up and running in less than a minute. In this tutorial I’m going to show you how to add a comment field to an existing MEAN.js Article example. You can see the finished application on http://mean.nikola-dev.com, and you can clone the source on GitHub.

I actually answered the question Adding comments to MEAN.JS articles on StackOverflow, and this posts is kind of an addition to that answer, with pictures (everyone likes pictures, right? 😉).

[toc]

Starting point

So, if you’ve followed the (ah, yet again mentioned) previous tutorial you have a running MEAN.js example on your DigitalOcean Droplet, whose front page looks like the image below if you’re logged in. You can simply register via mail (I didn’t implement any other methods like Facebook, Google, LinkedIn or GitHub for this tutorial).

Screen Shot 2015-06-28 at 14.32.35

Please note that yes, you can run this example locally on your computer too, but you would have to manually install the whole MEAN stack (namely MongoDB, Express.js and Node.js). If you wish to do so, you can take a look at the steps needed to do this from a rather popular tutorial How to get started on the MEAN stack. Rest of the tutorial, however, assumes you are testing this on DigitalOcean Droplet.

How to add a subdomain for Nodejs application on DigitalOcean droplet

When I was preparing this post I bought a domain just for testing purposes called nikola-dev.com and I wanted to have Node.js apps running on this VPS (behind a NGINX running as proxy, as we set it up in previous tutorial) but that they would be accessible from different subdomains (for example mean.nikola-dev.com). Below are the steps I needed to take in order to make this happen:

  1. Buy a domain (clearly you have done so smileyGlasses)
  2. Edit the Nameserver information in the admin dashboard of your domain provider (where you bought the domain) to the following three records:
    ns1.digitalocean.com, ns2.digitalocean.com, ns3.digitalocean.com
  3. Add the domain on DigitalOcean DNS settings page:
    digitalOcean_dns
  4. Delete /etc/nginx/sites-enabled/default
  5. Create /etc/nginx/sites-available/nikola-dev.com file with the following content (this will be a simple single HTML file which will list the available test apps on this server):
    server {
        listen 80;
        server_name nikola-dev.com;
        root /var/www/nikola-dev.com/public_html;
    }
  6. Create /etc/nginx/sites-available/mean.nikola-dev.com file with the following content (this will serve the actual Node.js app that we’re building in this tutorial):
    server {
        listen 80;
    
        server_name mean.nikola-dev.com;
    
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
  7. Restart NGINX:
    sudo service nginx restart

Adding a comment field to Article example

  1. In the file app/models/article.server.model.js add:
    comment: {
    	type: String,
    	default: '',
    	trim: true
    },

    For the reference, the whole app/models/article.server.model.js file contents should look like this:

    'use strict';
    
    /**
     * Module dependencies.
     */
    var mongoose = require('mongoose'),
            Schema = mongoose.Schema;
    
    /**
     * Article Schema
     */
    var ArticleSchema = new Schema({
            created: {
                    type: Date,
                    default: Date.now
            },
            title: {
                    type: String,
                    default: '',
                    trim: true,
                    required: 'Title cannot be blank'
            },
            content: {
                    type: String,
                    default: '',
                    trim: true
            },
            user: {
                    type: Schema.ObjectId,
                    ref: 'User'
            },
            comment: {
                    type: String,
                    default: '',
                    trim: true
            }
    });
    
    mongoose.model('Article', ArticleSchema);
  2. In the file public/modules/articles/views/create-article.client.view.html add the following content before the submit button:
    <div class="form-group">
    	<label class="control-label" for="comment">Comment</label>
    	<div class="controls">
    		<textarea name="comment" data-ng-model="comment" id="comment" class="form-control" cols="30" rows="10" placeholder="Comment"></textarea>
    	</div>
    </div>

    For the reference, the whole public/modules/articles/views/create-article.client.view.html file contents should look like this:

    <section data-ng-controller="ArticlesController">
            <div class="page-header">
                    <h1>New Article</h1>
            </div>
            <div class="col-md-12">
                    <form name="articleForm" class="form-horizontal" data-ng-submit="create()" novalidate>
                            <fieldset>
                                    <div class="form-group" ng-class="{ 'has-error': articleForm.title.$dirty && articleForm.title.$invalid }">
                                            <label class="control-label" for="title">Title</label>
                                            <div class="controls">
                                                    <input name="title" type="text" data-ng-model="title" id="title" class="form-control" placeholder="Title" required>
                                            </div>
                                    </div>
                                    <div class="form-group">
                                            <label class="control-label" for="content">Content</label>
                                            <div class="controls">
                                                    <textarea name="content" data-ng-model="content" id="content" class="form-control" cols="30" rows="10" placeholder="Content"></textarea>
                                            </div>
                                    </div>
    
    								<div class="form-group">
    								        <label class="control-label" for="comment">Comment</label>
    								        <div class="controls">
    								                <textarea name="comment" data-ng-model="comment" id="comment" class="form-control" cols="30" rows="10" placeholder="Comment"></textarea>
    								        </div>
    								</div>
    								
                                    <div class="form-group">
                                            <input type="submit" class="btn btn-default">
                                    </div>
                                    <div data-ng-show="error" class="text-danger">
                                            <strong data-ng-bind="error"></strong>
                                    </div>
                            </fieldset>
                    </form>
            </div>
    </section>
  3. In the file public/modules/articles/controllers/articles.client.controller.js adjust the create function to be:
    var article = new Articles({
    title: this.title,
    content: this.content,
    comment: this.comment
    });

    For the reference, the whole public/modules/articles/controllers/articles.client.controller.js file contents should look like this:

    'use strict';
    
    angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles',
            function($scope, $stateParams, $location, Authentication, Articles) {
                    $scope.authentication = Authentication;
    
                    $scope.create = function() {
                            var article = new Articles({
                                    title: this.title,
                                    content: this.content,
                                    comment: this.comment
                            });
                            article.$save(function(response) {
                                    $location.path('articles/' + response._id);
    
                                    $scope.title = '';
                                    $scope.content = '';
                            }, function(errorResponse) {
                                    $scope.error = errorResponse.data.message;
                            });
                    };
    
                    $scope.remove = function(article) {
                            if (article) {
                                    article.$remove();
    
                                    for (var i in $scope.articles) {
                                            if ($scope.articles[i] === article) {
                                                    $scope.articles.splice(i, 1);
                                            }
                                    }
                            } else {
                                    $scope.article.$remove(function() {
                                            $location.path('articles');
                                    });
                            }
                    };
    
                    $scope.update = function() {
                            var article = $scope.article;
    
                            article.$update(function() {
                                    $location.path('articles/' + article._id);
                            }, function(errorResponse) {
                                    $scope.error = errorResponse.data.message;
                            });
                    };
    
                    $scope.find = function() {
                            $scope.articles = Articles.query();
                    };
    
                    $scope.findOne = function() {
                            $scope.article = Articles.get({
                                    articleId: $stateParams.articleId
                            });
                    };
            }
    ]);
    
  4. In the file public/modules/articles/views/view-article.client.view.html add this just before the closing section tag:
    <p data-ng-bind="article.comment"></p>

    For the reference, the whole public/modules/articles/views/view-article.client.view.html file contents should look like this:

    <section data-ng-controller="ArticlesController" data-ng-init="findOne()">
            <div class="page-header">
                    <h1 data-ng-bind="article.title"></h1>
            </div>
            <div class="pull-right" data-ng-show="authentication.user._id == article.user._id">
                    <a class="btn btn-primary" href="/#!/articles/{{article._id}}/edit">
                            <i class="glyphicon glyphicon-edit"></i>
                    </a>
                    <a class="btn btn-primary" data-ng-click="remove();">
                            <i class="glyphicon glyphicon-trash"></i>
                    </a>
            </div>
            <small>
                    <em class="text-muted">
                            Posted on
                            <span data-ng-bind="article.created | date:'mediumDate'"></span>
                            by
                            <span data-ng-bind="article.user.displayName"></span>
                    </em>
            </small>
            <p class="lead" data-ng-bind="article.content"></p>
            <p data-ng-bind="article.comment"></p>
    </section>
  5. This is it, now you have a new field comment for each article:
    meanCommentAddingOnce added, you’ll see the comment in the article list:meanCommentAddedJPG
  6. What you should do now, and I hope it’s clear form these instructions here, is alter the editing part of the articles, so that they include the comment field.

Where to go from here?

This tutorial should have given you the basic understanding on how to add additional fields to the MEAN.js Article example, and you should be confident enough to starting adding your own fields and altering the example to your liking.

In the next tutorial we’ll take a look at how to add Image CRUD module to MEAN.js application with a single Yeoman command (I will update the link here once the tutorial is finished).

If you want to learn more about the MEAN stack, take a look at the blog2book Getting MEAN with MEMEs (yes, you can download it for free, though a coffee would be nice smileyGlasses).

Miscellaneou$

My new Lenovo Apple laptop with a custom hood

Update: Before I got rid of the Lenovo laptop, it looked like this:

lenovoFinal

TL;DR: Stickers can be seen here on StickerMule. If you happen to signup up via this link, you’ll get 10$ off of your next purchase. Thank me later… hand_rock_n_roll

Ok, ok, so before you start jumping about the title for thinking how did I not know about Apple buying Lenovo, and start calling your wallstreet woolf to get you a deal on some Apple stocks before they skyrocket again, let me calm you down by saying it’s just the stickers, it’s just the stickers 😉

So, as you may know I’m pretty much into Ionic framework lately and I stumbled upon some Ionic stickers on StickerMule and added them to cart immediately.

Then, I browsed through the site and as it seemed they offer you to upload your own stickers. So, I contacted their support team, and boy can I tell you their response time was fast. Like, super fast. They told me the details about the sizes and image quality in order for it to look good when printed.

Since I very much like MEAN stack and there were no stickers for it available yet, I made my own and you can take a look at them here on StickerMule.

I also ordered the sample pack for just 1$. The shipping price via air mail to Croatia was about 6$, but I have to say the shipping was indeed fast (less than a week, which to our country is, trust me I’m lying, fast).

The quality of the stickers is very good, and I like the personal touch where the person who packaged the stickers signed it by hand (see the image below).

Here are some pictures of the arrived lot:

IMG_4186 IMG_4189

Here’s the signature of the person who packaged it – thanks Wendy! IMG_4216

Here’s how my laptop now looks from the inside :). Yes, keep calm folks, I use R.A.T 7 and drink too much coffee too.

IMG_4218

And here’s how it looks from the outside. Before I only had the Apple logo in the middle (yeah, I happen to like Apple products, sue me smileyGlasses – erm, so why Lenovo then? Ah, that’s another story, ping me on mail or comments if you’re really intrigued). The blank space on the right hand side is left for a new sticker that’s coming soon 🙂

IMG_4219

Anyways, StickerMule has my recommendation for being awesome when it comes to stickers!

Ionic, Stack Overflow

cordova-plugin-whitelist Error 404 not found

profile for Nikola at Stack Overflow, Q&A for professional and enthusiast programmers
I’m a big fan of Stack Overflow and I tend to contribute regularly (am currently in the top 0.X%). In this category (stackoverflow) of posts I will will be posting my top rated questions and answers. This, btw, is allowed as explained in the meta thread here.

My question was:

I tried to run this code: cordova plugin add cordova-plugin-whitelist but what I keep getting is this:

Fetching plugin "cordova-plugin-whitelist" via plugin registry Error: 404 Not Found: cordova-plugin-whitelist at RegClient.<anonymous> (/usr/local/lib/node_modules/cordova/node_modules/cordova-lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:304:14) at Request._callback (/usr/local/lib/node_modules/cordova/node_modules/cordova-lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:246:65) at Request.self.callback (/usr/local/lib/node_modules/cordova/node_modules/cordova-lib/node_modules/npm/node_modules/request/request.js:236:22) at Request.emit (events.js:98:17) at Request.<anonymous> (/usr/local/lib/node_modules/cordova/node_modules/cordova-lib/node_modules/npm/node_modules/request/request.js:1142:14) at Request.emit (events.js:117:20) at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/cordova/node_modules/cordova-lib/node_modules/npm/node_modules/request/request.js:1096:12) at IncomingMessage.emit (events.js:117:20) at _stream_readable.js:943:16 at process._tickCallback (node.js:419:13)

Any ideas?

I actually found the answer to this myself:

From an official blog post, Cordova is moving their plugins to npm.

I installed the cordova-plugin-whitelist easily now with npm:

npm install cordova-plugin-whitelist
CodeProject, MEAN

How to get your MEAN stack up and running in less than a minute

Over the past year I’ve tried lots of options for hosting my MEAN applications, and finally I’ve settled for DigitalOcean. It’s true what they advertise – that you can have a SSD cloud server up and running in less than 55 seconds. However, you don’t have to go spending your hard earned cash just yet – I have a special deal with DigitalOcean and you can signup via this link and get 10$ immediately, which will be enough for 2 full months of non stop server running. They even provide you with API so that you can control your server, and this tutorial shows you how.

I don’t want to make it look like I’m pushing you on DigitalOcean – you can sign up with someone else if you like, I just recommend them because I had a good experience with them in the past and because it’s so easy to get a MEAN stack all pre-installed (more on this in a bit) and ready for use.

Create a droplet

Once you complete the sign up on DigitalOcean  you will be presented with a similar screen, as show on the image below, where you have to click on the Create Droplet button:

DO_1_createDroplet

Next, you have to name your droplet (cool name the folks at DigitalOcean chose to call their server instances) and select the size (the smallest one will be just fine here), just as it’s shown on the image below:

DO_2_nameAndSize

After this, you have to choose a region, as shown on the image below. Naturally, you’ll want to choose some location which is closer to your targeted audience.

DO_3_region

Now comes the most awesome part. In Select Image section you have tons of options ranging from the barebones distributions (Centos, Ubuntu, Debian, etc.), to the pre-built stacks (LAMP, LEMP, WordPress, ROR, MEAN, etc.) like shown on the image below. Here you have to choose the MEAN on 14.04 option (YMMV on the exact number), and this is awesome because with this droplet you won’t have to go through the hassle of installing Node.js, Express and MongoDB as we did in the first tutorial – it will be already done and waiting for you! B-E-A-utiful!

DO_4_image

Then, just wait a few seconds and your droplet will be ready:

DO_5_waiting

You’ll be redirected to the dashboard (once the droplet is created) which will look something like the image below:

DO_6_created

Connect to the droplet

On your email address you will receive instructions which will look something like on the image below:

DO_7_email

Now, using a SSH client of your choice (I’m currently on Windows so not much leeway here :)) connect to the droplet. The image below shows the setting from the Putty SSH client on Windows:

DO_8_putty_2

You have to connect with the root user and the password that was emailed to you. However, immediately upon logging in you will get a notification that you have to change the root’s password, as shown on the image below:

DO_9_rootLogin

Create a new user

Using root user in linux is bad practice, so now you’re going to create a new user with the following command:

useradd nikola

Of course, you can use any username you want. After this add the user to the sudo group by executing the following command:

gpasswd -a nikola sudo

The sudo group enables the user nikola to use the sudo command when using some commands that are restricted to root user. You can learn more about sudo here. The image below shows the example of the commands I just listed:

DO_10_userAdd

Run

Now just run

grunt

and if you visit your ip address on port 3000 you should see:

Screen Shot 2015-06-28 at 14.32.35

What you now have running is a well known MEAN.js framework. You may have also heard about MEAN.io and you can learn about the difference in my post about MEAN.io vs MEAN.js.

Use your own domain

In case you bought (or have somewhere hanging in the closet from the 90’s .com boom) a domain that you would like to use to point to your droplet you have to go to the DNS settings and add a domain like shown on the image below:

DO_11_DNS

Also, in your domain registrar (where you bought your domain – think Godaddy, Namecheap, Hostgator, etc.) you have to set the corresponding nameservers to:

  • ns1.digitalocean.com
  • ns2.digitalocean.com
  • ns3.digitalocean.com

You can learn more about this on the official Digital Ocean guide.

Using PM2

Running your Node.js application by hand is, well, not the way we roll. Imagine restarting the app every time something happens, or god forbid application crashes in the middle of the night and you find about it only in the morning – ah the horror. PM2 solves this by:

  • allowing you to keep applications alive forever
  • reloading applications without downtime
  • facilitating common system admin tasks

To install PM2, run the following command:

sudo npm install pm2 -g

To start your process with PM2, run the following command (once in the root of your application):

pm2 start server.js

As you can see from the output shown on the image below, PM2 automatically assigns an App name (based on the filename, without the .js extension) and a PM2 id. PM2 also maintains other information, such as the PID of the process, its current status, and memory usage.

PM2

As I mentioned before, the application running under PM2 will be restarted automatically if the application crashes or is killed, but an additional step needs to be taken to get the application to launch on system startup (boot or reboot). The command to do that is the following:

pm2 startup ubuntu

The output of this command will instruct you to execute an additional command which will enable the actual startup on boot or reboot. In my case the note for the additional command was:

sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u nikola

If you want to learn more about the additional PM2 options you can take a look at this post.

Using NGINX as a Reverse proxy in front of your Node.js application

Though this step is not mandatory, there are several benefits of doing so, as answered in this Stack Overflow question:

  • Not having to worry about privileges/setuid for the Node.js process. Only root can bind to port 80 typically. If you let nginx/Apache worry about starting as root, binding to port 80, and then relinquishing its root privileges, it means your Node app doesn’t have to worry about it.
  • Serving static files like images, CSS, js, and HTML. Node may be less efficient compared to using a proper static file web server (Node may also be faster in select scenarios, but this is unlikely to be the norm). On top of files serving more efficiently, you won’t have to worry about handling eTags or cache control headers the way you would if you were servings things out of Node. Some frameworks may handle this for you, but you would want to be sure. Regardless, still probably slower.
  • More easily display meaningful error pages or fall back onto a static site if your node service crashes. Otherwise users may just get a timed out connection.
  • Running another web server in front of Node may help to mitigate security flaws and DoS attacks against Node. For a real-world example, CVE-2013-4450 is prevented by running something like Nginx in front of Node.

So, with being convinced that having NGINX in front of Node.js application is a good thing, following are the steps on how to install and configure it.

First, update the apt-get package lists with the following command:

sudo apt-get update

Then install NGINX using apt-get:

sudo apt-get install nginx

Now open the default server block configuration file for editing:

sudo vi /etc/nginx/sites-available/default

and add this to it:

server {
    listen 80;

    server_name meantodo.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

This configures the web server to respond to requests at its root. Assuming our server is available at http://meantodo.com, accessing it via a web browser would send the request to the application server’s private IP address on port 3000, which would be received and replied to by the Node.js application.

Once you’re done with the setting you have to run the following command which will restart NGINX:

sudo service nginx restart

You can learn more about additional NGINX setting from quite a load of tutorials.

Faking RAM with swap

Since we chose the smallest droplet version of 512 MB we can use swap to make this droplet perform better. Swap is an area on a hard drive that has been designated as a place where the operating system can temporarily store data that it can no longer hold in RAM. For a more indepth tutorial on this you may want to check out official DigitalOcean guide.

In order to allocate a swap file space execute the following command:

sudo fallocate -l 1G /swapfile

Then restrict it to only root user by executing:

sudo chown 600 /swapfile

With the next two commands you actually setup the swap space and enable it:

sudo mkswap /swapfile
sudo swapon /swapfile

To view the swap space information you can execute:

sudo swapon -s

To enable swap automatically when the server restarts you have to add the following content to the /etc/fstab file:

/swapfile   none    swap    sw    0   0

Additionally, there are two more settings worth changing:

  • swappiness  – parameter which determines how often your system swaps data out of RAM to the swap space. The value is between 0 and 100 and represents a percentage (60 is the default, but we’ll use 10 since we’re on a VPS)
  • vfs_cache_pressure – parameter which determines how much the system will choose to cache inode and dentry information over other data (default value is 100, but we’ll use 50)

In order to make this change append the /etc/sysctl.conf file with the following content:

vm.swappiness=10
vm.vfs_cache_pressure = 50

Other security concerns

If you want to learn more on how to secure your droplet I advise you to go over the steps in the initial server setup with Ubuntu on official DigitalOcean tutorial.

A freakin’ 150+ page MEAN tutorial PDF

This is actually an excerpt from the 4 part tutorial series I wrote for HackHands. If you like you can also take a look at all those posts combined into one big PDF file via LeanPub:

Screen Shot 2015-06-28 at 14.45.42

 

P.S. It’s an intentional typo, since if you’re proud of getting something in production then it’s called a prouduction 😉

P.P.S. You can enter any amount (yes, even 0$) and I won’t take it against you ;), though a coffee would be nice smileyGlasses

hand_rock_n_roll on!

NodeJS, Quick tips

Using nginx as a reverse proxy in front of your Node.js application

This is a straight to point short tutorial on how to set up NGINX as a reverse proxy in front of a Node.js application, and although this is not mandatory, there are several benefits of doing so, as answered in this Stack Overflow question:

  • Not having to worry about privileges/setuid for the Node.js process. Only root can bind to port 80 typically. If you let nginx/Apache worry about starting as root, binding to port 80, and then relinquishing its root privileges, it means your Node app doesn’t have to worry about it.
  • Serving static files like images, CSS, js, and HTML. Node may be less efficient compared to using a proper static file web server (Node may also be faster in select scenarios, but this is unlikely to be the norm). On top of files serving more efficiently, you won’t have to worry about handling eTags or cache control headers the way you would if you were servings things out of Node. Some frameworks may handle this for you, but you would want to be sure. Regardless, still probably slower.
  • More easily display meaningful error pages or fall back onto a static site if your node service crashes. Otherwise users may just get a timed out connection.
  • Running another web server in front of Node may help to mitigate security flaws and DoS attacks against Node. For a real-world example, CVE-2013-4450 is prevented by running something like Nginx in front of Node.

So, with being convinced that having NGINX in front of Node.js application is a good thing, following are the steps on how to install and configure it.

First, update the apt-get package lists with the following command:

sudo apt-get update

Then install NGINX using apt-get:

sudo apt-get install nginx

Now open the default server block configuration file for editing:

sudo vi /etc/nginx/sites-available/default

and add this to it:

server {
    listen 80;

    server_name meantodo.com;

    location / {
        proxy_pass http://127.0.0.1:1337;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

This configures the web server to respond to requests at its root. Assuming our server is available at http://meantodo.com, accessing it via a web browser would send the request to the application server’s private IP address on port 1337, which would be received and replied to by the Node.js application.

Once you’re done with the setting you have to run the following command which will restart NGINX:

sudo service nginx restart

You can learn more about additional NGINX setting from quite a load of tutorials.

Books

The 7 Habits of Highly Effective People – Stephen Covey

My notes from the book The 7 Habits of Highly Effective People by Stephen Covey:

The significant problems we face can not be solved with the same level of thinking we were at when we created them – Albert Einstein

Is getting more things done in less time gonna make a difference? Or it will just increase the pace at which I react to the people and circumstances that seem to control my life? Could there be something that I should see on a more deeper fundamental way?

We are what we repeatedly do. Excellence then is not an act but a habit – Aristotle

“The work will come again, but childhood won’t”, said the father when he was called to work and previously he arranged to go to zoo with his children.

Too much undisciplined leisure time in which a person continually takes a course of least resistance gradually wastes a life.

Almost all of the world class athletes are visualizers. They see it, they feel it, they experience it before they actually do it. They begin with an end in mind.

Unexpressed feelings never die. They’re buried alive and come forth later in uglier form.

In families you can shift the focus from competition to cooperation with keeping a ‘family score’.

Like a body – television is a good servant but poor master.

And finally, the habits:

  • Be proactive
  • Begin with an end in mind
  • Put first things first
  • Think win-win
  • Seek first to understand, then to be understood
  • Synergize
  • Sharpen the say
Miscellaneou$

Cracking the Creativity Code Part 1 – Discovering ideas

I just finished a free course on Coursera called Cracking the creativity code and here are my notes from these very good lectures. The course is based on the book Cracking the creativity code by Arie Ruttenberg and Shlomo Maital.

[toc]

Course introduction

Creativity is an acquired skill – one that can improve with practice!

First part is discovery. Second is delivery – implementing ideas.

Zoom in, zoom out, zoom in –ZiZoZi method

Keneth Robinson: “Creativity is finding what you love to do when you’re playing, and then use that to make your work and become your living”

Discovery – generating novel and useful ideas that satisfy unmet needs

Delivery – implementing creative ideas in a sustained manner for the benefit of the largest number of people possible

book: Cracking the creativity code : ZoZ – Shlomo Maital, Arie

7challenges: Create a new kind of restaurant. Find a way to bring the Internet to 4.5 bilion people who currently lack it. Indoor cooking fire life saving. 1.3 bililion people without electricity. Babies forgotten in hot cars who die. New beverage that’s not in plastic. Forster creativity in elementary and secondary schools while improving basic skills and knowledge in math, reading and science. How to recycle food to feed hungry.

Week 1 – Session #1 Definition of creativity

Creativity – widening the range of choice.

Break the change of habit!

Out of our minds book by Sir

Norman Doidge – brain that changes itself

Week 1- Session #2 A first encounter with the ZiZoZi method

Why and for whom vs what can I invent.

Creativity is not IQ.

Creativity starts with WHY?

8 Da Vinci questions:

  • when am I most myself?
  • what is the ONE thing I could do, or stop doing that would most improve the quality of my life?
  • what is my greatest talent?
  • how can I get paid for what I love doing?
  • who are my role models?
  • what is my deepest passion?
  • what will be my life’s legacy?

Week 1- Session #3 Test your creativity: Torrance Creativity Test

IMG_3602 IMG_3603

Week 1- Session #4 Self-test your ‘discovery’ and ‘delivery’ skills

IMG_3604

Week 1- Session #5 The Imagination Elevator – a story you won’t believe

Gather all the wild ideas and “bring them to earth” in a shopping cart. Opposite way doesn’t work so well (to make a possible idea and then juice it up a bit). Go to the 989th floor in the imagination elevator.

The essence of discovery: embrace the mindset that all problems have a solution, we just need to discover them!

Week 1- Session #6 Widening the range of choices – the Zoom in/Zoom out/Zoom in framework

1. zoom in – understand the problem

2. zoom out – generate ideas (if people laugh at your idea, it means you’re on a right track since they haven’t seen this kind of thinking yet)

3. zoom back in an implement – so make the idea into practical solution

Week 1- Session #7 ZiZoZi in action: Stories to inspire & aspire

Human creativity has no limits, except for those that we place upon ourselves. Carl Young.

If you make something that exists already, make sure you make it at least 10 times better.

Week 1- Session #8 More ZiZoZi stories

Blackout restaurant, Curious case of Benjamin Button,.

One way of new ideas would be to take a look at history and those ideas that failed – make them better by using today’s technology.

Cool tie:

coolTie

Week 1- Session #9 How to build your creativity ‘muscles’

  1. Act, don’t just gripe
  2. Break the rules (intelligently) – first learn the rules
  3. Change your habits – go out of your comfort zone
  4. Develop resilience, embrace failure
  5. Explore dark corners, experiment everywhere
  6. Learn to focus
  7. Grow your persistence
  8. Hear, listen, teach
  9. Individualize: it’s always personal – if there’s something YOU need, make that
  10. Become who you are (join yourself)
  11. Have a microscope attached to telescope

Week 1- Session #10 Summary of Week One; Preview of Week Two

Master old knowledge and combine with creativity to create something new.

Mobley’s principles for greater creativity:

  1. Traditional teaching methods are worse than useless
  2. Becoming creative requires unlearning
  3. You can’t learn to be creative, you become creative by action. Fastest way to become creative is to socialize with creative people
  4. Creativity is highly correlated with self-knowledge and self-awareness
  5. Give your self a permission to be wrong

You can’t solve the problem with the same level of thinking that created the problem. Einstein.

Week 1 assessment 10/10!

Week 2- Session #1 ZiZoZi Framework Reviewed and viewed in action

Advertising agencies have a Creativity department

Week 2- Session #2 Case Study: How Thomas Edison lit up the world

Genius is 1% inspiration and 99% perspiration”. T. A. Edison

Edison invented phonograph. Create a platform not just a single product.

Week 2- Session #3 Zoom out: Collecting wild ideas

If you know exactly what you’re going to do, what is the point of doing it? ~ Pablo Picasso

Would you create an opera Carmen, for whom you would be criticised during your lifetime but admired when you die?

Week 2- Session #4 Zoom out: Benchmarking as a key tool

Best Practice Benchmarking. Benchmarking is a mindset. Observe everything and try to see where the world is going to be, not as it is today.

Week 2- Session #5 Is it innovative to borrow and adapt?

Story about M&M’s. Mars is also the chocolate bar from this man that went to war in Spain and figured out there how to bring chocolate to the battle field without melting (cover with hard candy).

Week 2- Session #6 How to challenge basic assumptions?

Ask the questions no one asks. Focus on the things that you usually take for granted and see how they could be impacted by a change in thinking that they are wrong.

If you fail, get the fuck up and try again.

Week 2- Session #7 Zoom in: Choosing the best of many ideas

Get out of your office to the place where the work is done by people using your product.

Week 2- Session #8 Managing the tradeoff between delivery and discovery

8 types of work ordered by my own preferences to solve business problems:

  • Application of technology (tech and engineering)
  • Counseling and mentoring (help others)
  • Managing people
  • Influence Through Language and Ideas (use of persuasion)
  • Enterprise Control
  • Creative production (generate new innovative business ideas)
  • Quantitative Analysis (math and financial analysis)
  • Theory Development and Conceptual Thinking (academic, conceptual approach)

Week 2- Session #9 Creativity everywhere: All the time, everyone, everything

Try to improve every aspect of your work from the ground up.

Week 2- Session #10 Case studies

If you find a good solution to your own need, you may find it to resonate with a lot of other people.

Week 2 assessment 9/10. The question “The famous NASA example of the Mars exploratory vehicle shows creative thinking IN the box because” is still puzzling…

 

Week 3- Session #1 The ZiZoZi method: continued. Zoom in: The role of accidental discovery and serendipity

Brilliant Blunder – Mario Livio

The greatest risk lies in never taking any risk in our thinking process.

Chance favors the prepared mind. ~ Pasteur

Week 3- Session #2 Sharpening observation skills

Observe people in what they do and make a program that will help them to do it more efficiently. Compare your program with the best alternative that’s already in the market.

If you need something, help yourself – it may be someone else will find it useful!

Week 3- Session #3 Empathic Discovery (Leonard & Rayport, “Spark Innovation Through Empathic Design” HBR Nov-Dec 1997

empathy vs sympathy. – Try to “feel” as you were the other person and have his problems.

Quicken story – people were using their check writing software for managing their small businesses.

Week 3- Session #4 The Role of Failure In Achieving Success

Centrino processor idea to actually lower the MHz and increase the battery life.

There is no failure, failure is just a next step (though, true, sometimes painful).

Week 3- Session #5 Zoom Out: Collecting data through direct observation

5 key types of information:

  1. Triggers of use
  2. Interaction with user’s environment
  3. User customization
  4. Intangible attributes
  5. Unarticulated user needs

Story about how chewing gum was invented.

Week 3- Session #6 The IDEO approach

Few key points, but one of the main is – don’t dismiss an idea just yet no matter how “weird” it may seem at that point.

Week 3- Session #7 Zoom In: Taming Wild Ideas

Tumor dissolving gun.

Week 3- Session #8 How to sell your ideas

Key questions:

  • The need
  • The difference (10x better)
  • The future
  • Cost and price

Week 3- Session #9 How to be creative In large organizations (Intrapreneurship)

Intrapreneurship, Gifford Pinchot

  1. Come to work willing to be fired
  2. Circumvent orders that prevent your dream
  3. Do any job needed
  4. Find people to help you and choose the best
  5. Work underground as long as you can
  6. Control your destiny
  7. It’s easier to ask for forgiveness than to ask for permission
  8. Be true to your goals but realistic in their achievement
  9. Honor your sponsors

Week 3- Session #10 What is YOUR story? Building powerful narratives. Case Studies

PCM – personal creativity machine: I stumble upon something that I have to do repeatedly on a daily basis and that bothers me and then I think about how to actually automatize that. I sit down and I build it (namely it’s usually software). The way I validate it is that I give it to someone and see how they use it, gather their info and try to make it better. If I see no practical use in this, I don’t tend to pursue it forward, I just leave it be. Excellent example of this is my free website for score tracking (http://carcassonne-scoring-board.com/).

Elon Musk is a superman: PayPal, Solar City, Tesla, PayPal

 

Week 4- Session #1 Creativity Exercises: Are You Working Out?

Norman Doidge – The brain that changes it self: “Brain changed its very structure with each different activity that it performed.” The more you work on discovering ideas, the more your brain gets at it.

Do a “What if” exercise.

Week 4- Session #2 What Scholars Know about Creativity: Research you can use

At the age of:

  • 5 nearly all children are geniuses by Torrance test
  • 10 their creativity level drops to 32%
  • 15 to 10%
  • 30 to 2%

Week 4- Session #3 On Being Walter Mitty. Is creativity fun, or painful?

It’s fine to dream, but you need to implement them also!

Week 4- Session #4 Life take two: On reinventing yourself and your career

The method of “adjacent possible”.

Interesting idea: come up with an idea, work on it hard and then set it aside and come to it a while (even maybe months) later. The fun fact is that the mind will be subconsciously working on it.

Week 4- Session #5 Secrets of Einstein, da Vinci and Edison

Best implementation wins, not the best idea.

Week 4- Session #6 Humble masterpieces: Stories of creative breakthroughs

Safety pin, Lipstick.

Week 4- Session #7 More Masterpieces: Creativity in Action

Barcode, Frisbee

Week 4- Session #8 Ideas proposed by students for the 7 Challenges

Week 4- Session #9 Torrance Test for Creative Thinking: Have you improved?

Week 4- Session #10 Course summary: What have you learned? What have you implemented? How have you changed?

Week 4 assessment 9/10.

Ionic, Stack Overflow

Ionic View Manage Apps

profile for Nikola at Stack Overflow, Q&A for professional and enthusiast programmers
I’m a big fan of Stack Overflow and I tend to contribute regularly (am currently in the top 0.X%). In this category (stackoverflow) of posts I will will be posting my top rated questions and answers. This, btw, is allowed as explained in the meta thread here.

My question was:

I uploaded a test app to Ionic (don’t know the exact name for this) with the command ionic upload from the command line, and I can access them nicely with the Ionic View application I have installed on my iPhone.

However, I remember that they have a web interface for this too, but can’t find the link for the life of me. I searched the website, went through my emails, googled, but nothing. I even found the same question on the official forum – sadly unanswered.

I actually found the answer to this myself:

And, sure enough, after going through my deleted emails I found a welcome email from Ionic stating that the login is at https://apps.ionic.io/login. Will reply to that official post too…

CodeProject, Ionic

Adding AdMob to Ionic framework application step by step

In case you’re looking for a way to implement Google AdMob ads in Ionic framework 3, then check out this tutorial: How to make money with Google AdMob ads in Ionic framework 3.

If you want, you can take a look at the screencast of this tutorial. This is actually my first shocked screencast blog post so go easy on me 🙂

I’ve been searching for a start to end tutorial on this but with no luck. Now, when I finally figured out how to use it, I’m documenting the exact steps which I did in order to get the AdMob working inside my Ionic app. You can fork the project from GitHub or download and test the .apk file on your device.

I broke down the steps in two parts: AdMob settings and Ionic settings.

AdMob settings

Let’s start with AdMob settings:

  1. Sign in /Sign up for AdMob at https://www.google.com/admob/
  2. Click the Monetize new app button:
    Screen Shot 2015-05-05 at 23.21.06
  3. If your app is not yet published you can add it manually:
    Screen Shot 2015-05-05 at 23.23.07
  4. Create new tracking ID:
    Screen Shot 2015-05-05 at 23.25.20
  5. Configure the adds type, size, placement, style, name:
    Screen Shot 2015-05-05 at 23.26.29
  6. You can read additional info on how to implement GA and AdMob, but for now let’s just click Done:
    Screen Shot 2015-05-05 at 23.28.10
  7. You will now see the following similar screen:
    Screen Shot 2015-05-05 at 23.30.11
    The most important thing to note here is this Ad unit ID, which in my test case is
    ca-app-pub-7957971173858308/3599533362

Ionic settings

I’m counting on the fact that you know how to use Ionic since you’re looking for a specific topic like this, so am going skip the part of actually explaining how to use the Ionic cli. Ok, enough chit-chat, now I’m going to show you the steps on how to implement AdMob in your Ionic project:

  1. Start a new Ionic blank project:
    ionic create IonicAdMobTest blank
  2. Add the platform for which you want to build the application:
  3. ionic platform add android

    In case you’re developing on a Mac, you can also choose to add:

    ionic platform add ios
  4. Add the cordova-plugin-admob plugin by entering the following command in your command prompt when in the root folder of your project:
    cordova plugin add com.rjfun.cordova.plugin.admob

    As a side note, you can always check the list of all installed plugins by executing:

    cordova plugin list
  5. Add the following code to your app.js file (located in the www folder) inside the .run function:
    .run(function($ionicPlatform) {
        $ionicPlatform.ready(function() {
            // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
            // for form inputs)
            if (window.cordova && window.cordova.plugins.Keyboard) {
                cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
            }
            if (window.StatusBar) {
                // org.apache.cordova.statusbar required
                StatusBar.styleDefault();
            }
    
            if(window.plugins && window.plugins.AdMob) {
                var admob_key = device.platform == "Android" ? "ca-app-pub-7957971173858308/3666912163" : "ca-app-pub-7957971173858308/3666912163";
                var admob = window.plugins.AdMob;
                admob.createBannerView( 
                    {
                        'publisherId': admob_key,
                        'adSize': admob.AD_SIZE.BANNER,
                        'bannerAtTop': false
                    }, 
                    function() {
                        admob.requestAd(
                            { 'isTesting': false }, 
                            function() {
                                admob.showAd(true);
                            }, 
                            function() { console.log('failed to request ad'); }
                        );
                    }, 
                    function() { console.log('failed to create banner view'); }
                );
            }
        });
    })

    Of course, change it according to your own admob_key which you obtained in the first part (step 8).

  6. Start the emulator by running:
    ionic build ios && ionic emulate ios
    
    //or, for android
    ionic build android && ionic emulate android
  7. and you should get the following screen in your emulated application:
    IonicAdMobTest
  8. You can clone the project from GitHub, or download the .apk (unzip needed) file and test on your Android device.

That’s all folks, hope this helps someone by saving time on endless testing as I did :/

Miscellaneou$

My blog listed along side the cool blogs from high rollers like Atwood, Spolsky, Skeet, Resig, Irish, Beck, Fowler…

A new cool project by Kilim Choi that lets you make a pull request with your engineering blog, that got quite a few stars on Github (4k+ currently).

And, that’s how my name got the be next to The Great Ones smileyGlasses

engineering-blogs

Make your pull request too!

Page 33 of 51« First...102030«32333435»4050...Last »

Recent posts

  • Discipline is also a talent
  • Play for the fun of it
  • The importance of failing
  • A fresh start
  • Perseverance

Categories

  • Android (3)
  • Books (114)
    • Programming (22)
  • CodeProject (35)
  • Daily Thoughts (77)
  • Go (3)
  • iOS (5)
  • JavaScript (127)
    • Angular (4)
    • Angular 2 (3)
    • Ionic (61)
    • Ionic2 (2)
    • Ionic3 (8)
    • MEAN (3)
    • NodeJS (27)
    • Phaser (1)
    • React (1)
    • Three.js (1)
    • Vue.js (2)
  • Leadership (1)
  • Meetups (8)
  • Miscellaneou$ (77)
    • Breaking News (8)
    • CodeSchool (2)
    • Hacker Games (3)
    • Pluralsight (7)
    • Projects (2)
    • Sublime Text (2)
  • PHP (6)
  • Quick tips (40)
  • Servers (8)
    • Heroku (1)
    • Linux (3)
  • Stack Overflow (81)
  • Unity3D (9)
  • Windows (8)
    • C# (2)
    • WPF (3)
  • Wordpress (2)

"There's no short-term solution for a long-term result." ~ Greg Plitt

"Everything around you that you call life was made up by people that were no smarter than you." ~ S. Jobs

"Hard work beats talent when talent doesn't work hard." ~ Tim Notke

© since 2016 - Nikola Brežnjak