Angular 4: Pass data parent to child component (part 2 of 2)

The full code for part 2 here and demo on gh-pages here.

Following on from part 1, next we will pass an array of objects between components.

In child.component.ts we add another @Input like this,

@Input() data: {name: string, id: number}[] = [];

Then to app.component.ts add,

  id: number = null;
  name: string = null;
  details: {name: string, id: number}[] = [];

Then in app.component.html we will add input forms for ‘id’ and ‘name’.

<label for="box2">id:</label>
<input type="number" name="box2" class="form-control" [(ngModel)]="id" />
<label for="box3">name:</label>
<input type="string" name="box3" class="form-control" [(ngModel)]="name" />
<p><button (click)="pushto()" class="btn btn-warning btn-sm">Submit</button></p>

again we are using [(ngModel)]. We also have a submit button and when this data is submitted the pushto() function is called.

The pushto() function in app.component.ts is,

pushto(){
    this.details.push({name: this.name, id: this.id});
    this.name = null;
    this.id = null;
  }

This will push a new object to the details array. Let’s display them on the root app page in app.component.html

<div class="col-xs-4 col-md-4">
  <p *ngFor="let element of details"><strong>name: </strong>{{element.name}} <strong>id: </strong>{{element.id}}</p>
</div>

Next we want to pass the array ‘details’ to the child component. To do this we include ‘[data]=”details”‘ in the <app-child> tag like this,

<app-child [quantity]="newvalue" [data]="details"></app-child>

So now in the child component child.component.html we will use *ngFor to loop through the array ‘data’.

<p *ngFor="let element of data"><strong>name:</strong> {{element.name}} <strong>id:</strong> {{element.id}}</p>

The full code for part 2 here and demo on gh-pages here.

Angular 4: Pass data parent to child component (part 1 of 2)

The full code for part 1 & 2 here and demo on gh-pages here.

This post explains how to pass data from a parent component directly into a child component without iteration using ngFor as we did in the other post on this same issue here.

With angular-cli previously installed, create a new project,

$ ng new angulardataparenttochild

Then change directory into that newly created directory,

$ cd angulardataparenttochild

Next create a child component,

$ ng g c child

In your editor place a tag <app-child$gt;$lt;app-child/$gt; in app.component.html to put the child component inside the parent component. Also add some bootstrap to make it nice! app.component.html should look like this,

<div class="container" style="border: 3px solid #515B89; background-color: #79809E; border-radius: 15px;">
  <div class="row">
    <div class="col-xs-12">
      <h1>
        {{title}}
      </h1>
    </div>
  </div>
  <div class="row">
    <div class="col--xs-12">
      <app-child></app-child>
    </div>
  </div>
</div>

Likewise the child.component.html file is

<div class="container" style="border: 3px solid #458075; background-color: #6D948C; border-radius: 15px;">
  <div class="row">
    <div class="col-xs-12">
      <p>
        child works!
      </p>
    </div>
  </div>
</div>

Let’s check this works with

$ ng serve

Navigate in your browser to localhost:4200

First be sure to import ‘Input’ into the top of the child component’s ts file child.component.ts,

import { Component, ElementRef, NgZone, OnDestroy, OnInit, Input } from '@angular/core';

Then just inside the child component’s class, in child.component.ts, use the input decorator to setup the data structure of the data being input to this child component,

@Input() quantity: number = null;

Add an input form to the root app, app.component.html

<input type="number" class="form-control" [(ngModel)]="value" (ngModelChange)="fun()"/>

Here we are using [(ngModel)] and setting any input to “value”. (ngModelChange)=”fun()” will call a function fun() whenever there is a change in the input form.

The full app.component.html file should look like this,

<div class="container" style="border: 3px solid #515B89; background-color: #79809E; border-radius: 15px;">
  <div class="row">
    <div class="col-xs-12">
      <h1>
        {{title}}
      </h1>
      <label for="box">Value:</label>
      <input type="number" class="form-control" [(ngModel)]="value" (ngModelChange)="fun()" />
      <p>value = {{ value }}</p>
      <p>newvalue = value + 2 = {{ newvalue }}</p>
    </div>
  </div>
  <div class="row">
    <div class="col--xs-12">
      <app-child [quantity]="newvalue"></app-child>
    </div>
  </div>
</div>

In app.component.ts just inside the “export class AppComponent(” we will define value and also in this class we will create the fun() function which increase “value” by 2, just to do something with it! We also set this then equal to “newvalue” and define that as we did with “value”.

So app.component.ts should look like this,

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'root app';
  value: number = null;
  newvalue: number = null;

  constructor(){
  }

  ngOnInit(){
  }

  fun(){
    this.newvalue = this.value + 2;
  }
}

We will display the values “value” and “newvalue” in app.component.html using interpolation which is just a fancy word for the double curly brackets {{ newvalue }},

<p>value = {{ value }}</p>
<p>newvalue = value + 2 = {{ newvalue }}</p>

Also in the file we will include child component using it’s selector which is app-child, like this,

<app-child></app-child>

But this where we pass the parent component value “newvalue” to the child value “quantity”.

<app-child [quantity]="newvalue"></app-child>

But we don’t want to pass it to the child.component.html just yet. We will like to get it into the child.componet.ts file first and do soemthing with it. We will again just increase it’s value by 2. This is done using the ngOnChanges() function.

But do use this you must import ‘OnChanges’ at the tope of child.component.ts,

import { Component, OnInit, Input, OnChanges } from '@angular/core';

Also you need to implement it with the class like this,

export class ChildComponent implements OnInit, OnChanges {...

Increasing the this.quantity value by 2 in ngOnChanges() is done like this,

  ngOnChanges(){
      this.quantity = this.quantity + 2;
  }

The function ngOnChanges() runs anytime the quantity value changes. In other words when there is an change to “newvalue” in the parent component. This is very useful!

Next we display that value in child.component.html using the {{quantity}}.

The child.component.html file,

<div class="container" style="border: 3px solid #458075; background-color: #6D948C; border-radius: 15px;">
  <div class="row">
    <div class="col-xs-12">
      <h3>child app</h3>
      <p>
        value + 4 = newvalue + 2 = quantity = <span *ngIf="quantity">{{quantity}}</span>
      </p>
    </div>
  </div>
</div>

However I found this always displayed the ‘quantity’ value as 2, even before anything was input.

As a result I put an if(quantity){…} around this line. So child.component.ts looks like this,

import { Component, OnInit, Input, OnChanges } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges {
@Input() quantity: number = null;

  constructor() {
  }

  ngOnInit() {
  }

  ngOnChanges(){
    if(this.quantity){
      this.quantity = this.quantity + 2;
    }
  }
}

The full code for part 1 & 2 here and demo on gh-pages here.

Angular 4 & D3.js

Code is on github on d3graph repo.
View demo on gh-pages.


Having angular-cli installed (how to install angular-cli), then create a project called ‘angular-d3-example’

$ ng new angular-d3-example

Next we’ll add a component for the graph, which we’ll call ‘d3graph’,

$ ng g c d3graph

Add the selector to the app.component.html file.
We need to install the service ‘d3-ng2-service’. The github page for this is here. Install this service with npm using,

$ npm install d3-ng2-service --save

You will need to import the ‘D3Service’ from ‘d3-ng2-service’ by adding to the top of app.module.ts,

import { D3Service } from 'd3-ng2-service';

Also import ‘D3Service’ to the providers array in the same file.
Then module.ts should look like this,

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { D3graphComponent } from './d3graph/d3graph.component';

import { D3Service } from 'd3-ng2-service'; // <-- import statement

@NgModule({
  declarations: [
    AppComponent,
    D3graphComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [D3Service], // <-- import provider
  bootstrap: [AppComponent]
})
export class AppModule { }

Services can be greated with angular-cli using,

$ ng g s SERVICENAME

At this stage it is a good idea to check everything is working by running,

$ ng serve

and navigate to http://localhost:4200 where is should say ‘app works!’ and below it ‘d3graph works!’

We’ll create a bar chart using,

data = [
          {name : 'A', yVal : 1},
          {name : 'B', yVal : 4},
          {name : 'C', yVal : 2},
          {name : 'D', yVal : 3}
      ];

The d3graph.componet.ts will look like this,

import { Component, ElementRef, NgZone, OnDestroy, OnInit } from '@angular/core';

import {
  D3Service,
  D3,
  Axis,
  BrushBehavior,
  BrushSelection,
  D3BrushEvent,
  ScaleLinear,
  ScaleOrdinal,
  Selection,
  Transition
} from 'd3-ng2-service';


@Component({
  selector: 'app-d3graph',
  template: '<svg width="200" height="200"></svg>'
})
export class D3graphComponent implements OnInit {
  private d3: D3;
  private parentNativeElement: any;
  private d3Svg: Selection<SVGSVGElement, any, null, undefined>;

  constructor(element: ElementRef, private ngZone: NgZone, d3Service: D3Service) {
    this.d3 = d3Service.getD3();
    this.parentNativeElement = element.nativeElement;
  }

  ngOnInit() {
            let self = this;
            let d3 = this.d3;
            let d3ParentElement: any;
            let svg: any;
            let name: string;
            let yVal: number;
            let colors: any = [];
            let data: {name: string, yVal: number}[] = [];
            let padding: number = 25;
            let width: number = 500;
            let height: number = 150;
            let xScale: any;
            let yScale: any;
            let xColor: any;
            let xAxis: any;
            let yAxis: any;

    if (this.parentNativeElement !== null) {
      svg = d3.select(this.parentNativeElement)
          .append('svg')        // create an <svg> element
          .attr('width', width) // set its dimensions
          .attr('height', height);

      colors = ['red', 'yellow', 'green', 'blue'];

      data = [
          {name : 'A', yVal : 1},
          {name : 'B', yVal : 4},
          {name : 'C', yVal : 2},
          {name : 'D', yVal : 3}
      ];

      xScale = d3.scaleBand()
          .domain(data.map(function(d){ return d.name; }))
          .range([0, 200]);

      yScale = d3.scaleLinear()
          .domain([0,d3.max(data, function(d) {return d.yVal})])
          .range([100, 0]);

      xAxis = d3.axisBottom(xScale) // d3.js v.4
          .ticks(5)
          .scale(xScale);

      yAxis = d3.axisLeft(xScale) // d3.js v.4
          .scale(yScale)
          .ticks(7);

        svg.append("g")
        .attr("class", "axis")
        .attr("transform", "translate(" + (padding) + "," + padding + ")")
        .call(yAxis);

	       svg.append('g')            // create a <g> element
         .attr('class', 'axis')   // specify classes
	       .attr("transform", "translate(" + padding + "," + (height - padding) + ")")
         .call(xAxis);            // let the axis do its thing

      var rects = svg.selectAll('rect')
          .data(data);
          rects.size();

      var newRects = rects.enter();

      newRects.append('rect')
          .attr('x', function(d,i) {
            return xScale(d.name );
          })
          .attr('y', function(d) {
              return yScale(d.yVal);
            })
	        .attr("transform","translate(" + (padding -5  + 25) + "," + (padding - 5) + ")")
          .attr('height', function(d) {
              return height - yScale(d.yVal) - (2*padding) + 5})
          .attr('width', 10)
          .attr('fill', function(d, i) {
            return colors[i];
          });
     }
   }
 }

Should look like this,

Code is on github on d3graph repo.
View demo on gh-pages.

Angular 4: Simple Routing

All code is on github https://github.com/shanegibney/angular-routing
A demo is available on gh-pages https://shanegibney.github.io/angular-routing/

Start a new project using angular-cli,

$ ng new angularRouting

Move into the project root directory

$ cd angularRouting

Create app-routing.module.ts

$ ng g module app-routing

Set the app-routing.module.ts to add components and routes. Also note the changes to ngModule imports and exports.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { InfoComponent } from '../info/info.component'
import { AboutComponent } from '../about/about.component'

const routes: Routes = [
{
path: 'about',
component: AboutComponent,
},
{
path: 'info',
component: InfoComponent,
},
];

@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [
RouterModule
],
declarations: []
})
export class AppRoutingModule { }

Next create two components ‘about’ and ‘info’.

$ ng g c info
$ ng g c about

To app.module.ts import the AppRoutingModule and to ngModule imports add AppRoutingModule, so that app.module.ts looks like this,

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppRoutingModule } from './app-routing/app-routing.module';

import { AppComponent } from './app.component';
import { InfoComponent } from './info/info.component';
import { AboutComponent } from './about/about.component';

@NgModule({
declarations: [
AppComponent,
InfoComponent,
AboutComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRoutingModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

To app.component.html add the element. This is where the component will render. Also add link to the components,

<h1>
{{title}}
</h1>
<a routerLink="/info" routerLinkActive="active">Info</a>
<a routerLink="/about" routerLinkActive="active">About</a>
<router-outlet></router-outlet>

Add the following routes to redirect empty routes ” and wildcards ‘**’ to home,

    
{
path: '',
redirectTo: '/home',
pathMatch: 'full',
},
{
path: '**',
redirectTo: '/home',
pathMatch: 'full'
}

Note Angular checks the routes in order so empty routes and wildcards must be after all other routes with the wildcard route at the end.

All code is on github https://github.com/shanegibney/angular-routing
and a demo is available on gh-pages https://shanegibney.github.io/angular-routing/

Useful link: http://shermandigital.com/blog/configure-routing-in-an-angular-cli-project/

Angular 4: Building a Simple Service

Create the project with angular-cli

$ ng new angular-service-project

Create a service with angular-cli

The service was created with,

$ ng g s example-service

where ‘g’ is a shortcut for ‘generate’ and ‘s’ is a shortcut for ‘service’.

The actual service is at: example-service-service.ts

import { Injectable } from '@angular/core';
@Injectable()
export class ExampleServiceService {
someMethod(){
return "Heya!";
}
constructor() { }
}

Then make the changes to app.component.ts

import { Component, OnInit } from '@angular/core'; // added OnInit
import { ExampleServiceService } from './example-service.service' // added this import

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [ExampleServiceService]
})
export class AppComponent {
title = 'app works!';
example: string;
constructor(private _exampleServiceService: ExampleServiceService){ // added this constructor
}
// added this ngOnInit method
ngOnInit(){
this.example = this._exampleServiceService.someMethod();
}
}

Get example into the app.component.html file,

<h1>{{ title }}</h1>
<h3>{{ example }}</h3>

To make this service available to all components, cut the line

providers: [ExampleServiceService]

from app.component.ts and put it is app.module.ts and also make it available with

import { ExampleServiceService } from './example-service.service'

app.module.ts should look like this,

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { ExampleServiceService } from './example-service.service'
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [ExampleServiceService],
bootstrap: [AppComponent]
})
export class AppModule { }

Angular4: Pass data from parent to child component (part 5)

Set  up an ng project,

$ ng new angularcomponentpassing

Create a new component,

$ ng g c cockpit

File: cockpit.component.ts

import { Component, OnInit, Input } from '@angular/core';

@Component({
selector: 'app-cockpit',
templateUrl: './cockpit.component.html',
styleUrls: ['./cockpit.component.css']
})
export class CockpitComponent implements OnInit {
@Input('srvElement') element: {name: string, id: number;}
constructor() { }

ngOnInit() {
}
}

Note: ‘srvElement’ is an alias for ‘element’ and can be left out above like this,

@Input() element: {name: string, id: number;}
constructor() { }

File: cockpit.component.html

<hr>
<p>
cockpit works!
</p>
<p><strong>Name:</strong> {{ element.name }}, <strong>id:</strong> {{ element.id }}</p>

File: app.component.ts

import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})

export class AppComponent {
title = 'app works!';
serverElements = [{name: 'John', id: 8}, {name: 'Matt', id: 10}];
}

File: app.component.html

<h1>
{{title}}
</h1>
<app-cockpit *ngFor="let serverElement of serverElements" [srvElement]="serverElement">hello</app-cockpit>

If the alias for ‘element’, which is ‘srvElement’ is not used then the above line should be,

<app-cockpit *ngFor="let serverElement of serverElements" [element]="serverElement">hello</app-cockpit>

Angular 4: Deploy to gh-pages (part 4)

Presuming: you have an Angular 2 or 4 project ready to deploy to gh-pages, and that you’ve created a github repo connected to your local directory and git inited it. Also you need to have installed and be using angular-cli. If not look at this post.

Angular 4 projects can be deployed on gh-pages by first installing the npm package angular-cli-ghpages,

$ sudo npm i -g angular-cli-ghpages

The previous command is run in your local master branch. There is no need to create a local gh-pages branch or in fact a remote one in your repository. First create your dist folder and set the base-href with,

$ ng build --prod --base-href https://<USERNAME>.github.io/<REPONAME>/

Do not forget the trailing forward slash at the end.

Then sent this to your remote gh-pages branch, which does not need to be previously created.

$ sudo angular-cli-ghpages --branch gh-pages

This is also run in your local master branch. Running this commands as deparately as above did not work for me, I had to create a script called ‘deploy’ which I placed at the end of the package.json “scripts” object, like this,

"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"deploy": "ng build --prod --base-href https://shanegibney.github.io/basic-maths-app/ && angular-cli-ghpages --branch gh-pages"
},

Then run this script with,

$ sudo npm run deploy

Then navigate to,

https:/<USERNAME>/.github.io/<REPO-NAME>/

The following blog post from shermandigital.com may be useful.

Angular 4: Forms (part 3)

Let’s add an input for with type=”number”. This will be in the sum app’s html file, src/app/sum/sum.component.html

What’s important here in the ngModel and it’s round and square brackets. We can set the inputted value to num1 with,

[(ngModel)]="num1"

Also the onSum() method is called when the button is clicked.

We need to set num1, num2 and sum variables in src/app/sum/sum.component.ts and create the onSum() method which is called to sum the numbers when the button is clicked.

Angular 4: Bootstrap & Components (part 2)

First install Bootstrap,

$ npm install --save bootstrap

Then add bootstrap to .angular-cli.json which can be found in the root of the project. Find the ‘styles’ and add the path for bootstrap like this,

"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"styles.css"
],

Then in the project root run,

$ npm install,

Create a component called ‘sum’ with,

$ ng g c sum

Next get the sum component into the root component.
Go to src/app/app.component.html and place the selector for the sum component which is,

<app-sum></app-sum>

This gets placed as follows,

Now that we’ve placed our sum component in the root component we would like to set it’s contents. This can be done in src/app/sum/sum.component.html

And so at http://localhost:4200 we should see the contents of the sum component inside the root component like this,

Angular 4: Getting started Install angular-cli (part 1)

We’ll create a simple app with Angular 4 which will sum two numbers input into a form.

First install Angular CLI (https://cli.angular.io/)

$ npm install -g @angular/cli

Create a new project called mathapp,

$ ng new mathapp

Move into this newly created directory,

$ cd mathapp

Now create a component called sum

$ ng g c sum

where g is short for generate and c is for component.

Next be sure to be in the same directory that has package.json and install all packages in there with npm. yarn is also a good package manager, consider faster than npm because it will not install package dependecies already installed in previous packages.

$ npm install

Now let us run the server with,

$ ng serve

Navigate to http://localhost:4200

and you should see the text,

So now we are well on our way! Well done!

Angular 4: Generating Components and How to Use

To create a new component in Angular 4 automatically with the Angular CLI, in the projects root directory type,

$ ng generate component my-component

Where ‘my-component’ is the name of the component. The commands ‘generate’ and ‘component’ can respectively be replaced with ‘g’ and ‘c’. The following command does the same as the above command,

$ ng g c my-component

This will create a new folder in the app directory with the following files,

The command also makes changes to the file src/app/app.module.ts on lines 7 and 12,

Also the file src/app/my-component/my-component.component.ts is created as follows,

These changes could all be implemented manually instead of using the command.

To create a new component without the src/app/my-component/my-component.component.spec.ts which is for unit unit testing,

$ ng g c my-component --spec false

my-component.component.ts contains

templateUrl: './my-component.component.html',

to use the contents of srcv/app/my-component.component.html in the root app html file src/app/app.component.html add a custom html tag with the component name as follows,

<app-my-component></app-my-component>

Angular 4: Data Binding Two-Way-Binding

Initially the button is disabled until a username is input, after which time it is possible to reset the username by clicking the button.


In app.component.ts he simply declare two variables and set ‘username’ to an empty string. The function clears the string and resets the username.

export class AppComponent {
username: string = '';
allowButton: boolean = false;
onUsernameReset(){
this.username = '';
}
}

In app.component.html we use [(ngModel)] for two-way-databinding. This uses both square and round brackets. The input is set to ‘username’ and because of the two-way-binding this is available everywhere, e.g. for string interploation on the next line using {{ username }} and for property binding [disabled]=”!username”

<div class="container">
  <div class="row">
    <div class="col-md-4">
     <label for="box">Username:</label>
     <input name="box" type="text" class="form-control" [(ngModel)]="username"/>
     <p> {{ username }} </p>
     <button class="btn btn-primary" [disabled]="!username" (click)="onUsernameReset()">Reset username</button>
    </div>
  </div>
</div>

The ‘click’ event is put in round brackets and it calls the function onUsernameReset() which can be found in app.component.ts

Angular 4: Data Binding Event Binding

When an event occurs i.e. clicking a button we want a function onButton() to be called.

In app.component.ts we have the function onButton() which simply logs a few words to the console,

export class AppComponent {
onButton(){
   console.log("You pressed it, well done!")
   }
}

In app.component.html the event, in this case ‘click’, is in round brackets,

<button class="btn btn-primary" (click)="onButton()">Button</button>

Angular 4: Basic Setup & Bootstrap

https://cli.angular.io/

Install Angular 4 using the Angular CLI tool,

$ npm install -g @angular/cli

Create a new app or project,

$ ng new my-new-app

This creates a new directory, next move in to it,

$ cd my-new-app

Run the app in development,

$ ng serve

Install bootstrap,

$ npm install --save bootstrap

Then add bootstrap to .angular-cli.json which can be found in the root of the project. Find the ‘styles’ and add the path for bootstrap like this,

"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"styles.css"
],

It may be necessary here to run,

$ npm install

from the project root directory, the directory containing the node_modules directory.

You can then use bootstrap in my-new-app/src/app/app.component.html

<div class="container">
  <div class="row">
    <div class="col-md-4">one</div>
    <div class="col-md-4">two</div>
    <div class="col-md-4">three</div>
  </div>
</div>

GIT Notes: Remote Repositories

GIT Succinctly – free eBook from Synfusion

    Chapter 6 Remote Repositories

Manage connections to other repositories, and list them with,

$ git remote

To get more information about remote repos,

$ git remote -v

Create a new connection to a remote repository,

$ git remote add <user-name> <path-to-repo>

Now you can reach that repo with user-name instead of typing it all out.
Git accepts protocols, file://, ssh://, http//, and git://
example,

$ git remote add <user-name> ssh://git@github.com/<user-name>/<repo-name>.git

Repo can be found at, github.com/user-name/repo-name.git
Delete a remote connection,

$ git remote rm <repo-name>

Remote branches represent a branch is someone else’s repository.
fetching, the act of downloading branches from another repository.

$ git fetch <repo> <branch>

Omit branch if you want all branches in a repository.
View downloaded branches with,

$ git branch -r

Remote branches are prefixed with ‘origin’. You can look at their history with,

$ git checkout

Remote branches behave like read-only branches until you integrate them into your local repository.
Display new updates from ‘origin/master’ not your local ‘master’, like this,

$ git log master..origin/master

You can checkout remote branches but this will put you in a detached HEAD state, and without a branch changes will be lost, unless you create a new local branch tip to reference them.

Incorporate changes from origin/master into a local branch,

$ git checkout <mybranch>
$ git fetch origin
$ git merge origin/master

This results in a “3-way” merge. Your master has merged with origin/master and that then merges with your branch. This will produce many meaningless merge commits.
This can be overcome with rebasing,

$ git checkout <mybranch>
$ git fetch origin
$ git rebase origin/master

‘pull’ is the ‘fetch/merge’ sequence combined.
Fetch the origin’s master branch and merge it into the current branch.

$ git pull origin/master

That will merge, but if you’d prefer to rebase use the ‘–rebase’ flag, which I think would be used like this,

$ git pull --rebase origin/master (not certain that’s where the flag goes in this command)

Send local branch to a remote repository,

$ git push <remote> <branch>

This creates a local branch on the remote repository. (So a local branch can appear on a remote repository if someone remotely pushes to it. I think!!!)

Public repositories are bare repositories, they do not have working directory.

Create a bare repository with,

$ git init --bare <path>.git

Bare repositories only function as storage facilities.

A push to a origin/master may be aborted because your local branch is not in sync.
Synchronise with a central repository,

$ git fetch origin master
$ git rebase origin/master
$ git push origin master

GIT Notes: Branches

GIT Succinctly – free eBook from Synfusion

    Chapter 5 Branches

A new branch is a new development environment with an isolated working directory, staging and project history.
‘git branch’ is used for listing, creating, and deleting branches.
To view existing branches,

$ git branch

The output will indicate the currently checkedout branch with an asterisk.
The master branch is git’s default branch.
Create a new branch,

$ git branch <branch-name>

This does not switch you to the new branch, only creates a pointer to the current HEAD. (but I thought HEAD was the current commit!)
To switch branch,

$ git checkout <branch-name>

Initially both branches reference the same commit, but any new commits will be exclusive to the current branch and so each branch will have a HEAD of its own.
To delete a branch,

$ git branch -d <branch-name>

This will not delete branches with unmerged conflicts, to force the deletion,

$ git branch -D <branch-name>

After switching to a new branch, your working directory is updated to match the specified branche’s commit. (I think this just means, the latest commit or HEAD will be on this branch. Isn’t that obvious, since the HEAD is another name for the latest commit? Or maybe the HEAD is always the latest commit, but will take it from the checked out branch.)
Make sure your working directory is ‘clean’, meaning no uncommitted changes, before checking out another branch. Otherwise ‘git checkout’ could overwrite your modifications.
Using ‘git checkout’ with tags and commit IDs puts you in a detached HEAD state. his means you are not on a branch anymore, you are directly viewing a commit and will lose all work as soon as you switch to a real branch.
Creating a new branch in a detached HEAD state,

$ git checkout -b <new-branch-name>

This is a new branch reference to the formerly detached state.
In this case ‘-b’ is a shortcut for the two commands,

$ git branch <new-branch-name>
$ git checkout <new-branch-name>

(But how do you use ‘git checkout’ with tags and commit IDs to create a detached HEAD state.)
Merging is the process of pulling commits from one branch into another.
Merge methodologies: “fast-forward” merge, or a “3-way” merge.
The branch you want to merge into must be checked out and the target branch will remain unchanged.
To merge a branch called ‘sidebranch’ in master,

$ git checkout master
$ git merge sidebranch

This leaves sidebranch unchanged.
“fast-forward” merge: I create a new branch off master and add two commits to it, this type of merge syncs master with that latest branch commit. Master then contains all desired history and the branch can be deleted.
This was a simple situation because there were no extra commits on the master. If there are use a “3-way” merge.
“3-way” merge: I create a new branch off master and add two commits, during which time the master gets a new commit. To merge git generates a new merge commit, a combined snapshot of both branches. This commit has two parents commits and a history from both branches.
After using,

$ git checkout master

both types of merge use the same command,

$ git merge sidebranch

Two branches that make different changes to the same code portion is a merge conflict. This can not occur in a “fast-forward” merge.
When a merge conflict occurs use,

$ git status

If you get a merge conflict open the file and you’ll see something like,

<<<<<<< HEAD
This content is from the current branch.
=======
This is a conflicting change from another branch.
>>>>>>> some-feature

Delete the content you don’t want including all of the <<<<<< , ======= , >>>>>>> lines also.
Then do,

$ git add <file>

and

$ git commit

Rebasing requires a branch to be checked out,

$ git checkout branch

Then to move the entire branch onto the tip of master,

$ git rebase master (but what happens to the branch then?)

This results in the same snapshot as if branch was merged with master.
“3-way” merge results in an extra merge commit. Rebasing has no extra commits and results in a cleaner linear history.
Change commits as you’re moving them to the new base, by specifying an interactive rebase,

$ git rebase -i master

This populates an editor with commits from the branch.
Specify an interactive rebase as follows,

pick 58dec2a First commit for new feature
squash 6ac8a9f Second commit for new feature

‘pick’ moves the first commit to the new base just as in ‘git rebase’. ‘squash’ combines the second commit with the previous one, so you end up with one commit containing all the changes.
Interactive rebasing lets you rewrite a branches history, you can add intermediate commits, then go back and fix them into more meaningful progression afterwards.
never rebase a branch that has been pushed to a public repository

GIT Notes: Undoing Changes

GIT Succinctly – free eBook from Synfusion

    Chapter 4 Undoing Changes

Undoing changes in git could mean,

  • Undo changes in working directory
  • Undo changes in staging area
  • Undo a entire commit

Changes can be made by deleting a commit or by using a new commit to undo changes introduced by the first commit.
The recent commit is the ‘HEAD’.
Make the working directory and the stage, match the files in the most recent commit. (This will actually change files in your working directory!!!)

$ git reset
$ git reset --hard HEAD (not sure about difference between these?)

To get rid of (meaning to delete) untracked files,

$ git clean

‘-f’ option forces deletion of these files,

$ git clean -f

(What is the difference between an ‘option’ e.g ‘-f’ and a ‘flag’ e.g. –hard? Or are these terms used interchangeable? Perhaps options are single character and reppended with a single hyphen and flag are mutiple charactered and preppended with double hyphens?)
A ‘reset –hard’ makes all files in the working directory and staging sync with the lastest commit.
Make a single file in the working directory match the version in the most recent commit, (bypasses staging)

$ git checkout HEAD

You can replace HEAD with a commit ID, branch or tag to make the file match the version in that commit. This command is like
NB Do Not Try this with ‘git reset’
To unstage a file,

$ git reset HEAD

This will not change the working directory.
To reset every file in the working directory and staging,

$ git reset --hard HEAD

This results in an unstaged modification in ‘git status’.
Undoing commits:
‘reset’ will remove it from project history
‘revert’ which generates a new commit that gets rid of changes introduced in the original.
To move the HEAD reference back one commit,

$ git reset HEAD ~1

This removes the most recent commit. Or you can go back two commits with ‘~2’, this also removes the two most recent commits. Not good to do this on public projects with other collaborators.
Reverting adds a new commit that undoes the problem commit

$ git revert

This takes the changes in the specified commit, figures out how to undo them, and creates a new commit with the resulting changeset. This t=is the way to undo a commit with a public repository.
Replace a previous commit instead of creating a new one,

$ git commit --amend

This rewrites history!

GIT Notes: Recording Changes

GIT Succinctly – free eBook from Synfusion

    Chapter 3 Recording Changes

A ‘snapshot’ is a complete record of state of files, not of differences between other states.
‘staging’ allows you choose what changes go into the commit.
To stage files,

$ git add (can multiple files be listed here?)

or to stage all,

$ git add .

To stop tracking a file, in other words to delete it from the project but not the working directory,

$ git rm --cached(can multiple files be listed here)

To view status of working directory and staging area,

$ git status

To output status of every unstaged change in your working directory,

$ git diff

To output difference of all staged changes

$ git diff --cached

To display committed snapshots,

$ git log
$ git status (what does this get?)

We start with ‘working directory’. This is ‘staged’ with ‘git add .’ and it is now a ‘staged snapshot’ which can then be ‘commited’ to ‘history’. And I suppose it is then ‘pushed’ to a remote repo.
A ‘commit’ is a saved version or ‘snapshot’ of the project, containing user info, date, commit message and SHA-1 checksum of entire contents.
A ‘commit’ is a step removed from working directory.
To commit staged snapshot to and add it to the history of the current branch,

$ git commit

You’ll be asked for a commit message,
Alternatively if the message is short you can use,
$ git commit -m “commit messsage goes here”
Display current branch’s commits,

$ git log (already mentioned above)

For working directory and stage we use: git add, git rm, and git status
For commit history: git commit, and git log
To display each commit on a single line,

$ git log -oneline (is the single hyphen correct)

To display history of an individual file,

$ git log --oneline (is the double hyphen correct?)

Filter commits, display commits contained in but not in . Both arguments can be commit ID, branch name or a tag,

$ git log .. (this is not clear)

To see what files were effected by a particular commit, display a diffstat of the changes in each commit,

$ git log -stat

Tags are simple pointers to commits. Create a new tag,

$ git tag -a v1.0 -m "Stable release"

-a creates an annotated tag and -m lets you record a message.
List your existing tags,

$ git tag

GIT Notes: Overview & Configuration

GIT Succinctly – free eBook from Synfusion

    Chapter 1 Overview
  • working directory
  • staging
  • commited history
  • development branch
    Chapter 2 Configuration

Configuration file in home directory,

$ cat ~/.gitconfig

To git init a directory,

$ git init <path-to-directory>

Omit path to git init current directory.

Includes a directory ‘.git’.
‘clone’ downloads a complete copy of repo. Clone can be used instead (or as well as) ‘git init’.

$ git clone ssh://@/path/to/repo.git (never used ssh here before)

Could also

$ git clone

Python append variable to ever occurrence of a substring

Using the function from Stackoverflow,

‘s’ is the original string, ‘sub’ the substring to be replaced, ‘repl’ the string to replace it with and ‘nth’ the nth occurence of the substring in the string ‘s’.

def nth_repl(s, sub, repl, nth):
find = s.find(sub)
i=find != -1
while find != -1 and i != nth:
find = s.find(sub, find+1)
i+=1
if i == nth:
return s[:find]+repl+s[find+len(sub):]
return s

Count occurences of the substring,

num = str.count("text")

Placing this function in a loop which will iterate through every occurrence of the substring in the string and append the index of each nth occurrence with that index.

for i in range(0,num+1):
newstr = nth_repl(str, "text", "text%d"%(i-1), i)
str = newstr

And then,

print str

Hardening SSH

SSH created key-pair

More information on this topic at securing-your-server.
On your local machine, create a 4096-bit RSA key-pair,

$ ssh-keygen -b 4096

If you get a message to say that this already exists or to over write a file, then do not proceed, unless you want to create a new key-pair. If one exists, then it is probably being used to ssh into somewhere else. Don’t want to mess that up!!!
To check if it already exists,

$ cat ~/.ssh/id_rsa

Copy key to remote server

Next copy this key to the remote server,

$ ssh-copy-id <username>@<remote-server>

Now login to the remote server. You should not be asked for the password, since the key-pair now exists.

We do not want root logins. Open,

/etc/ssh/sshd_config and navigate to ‘#Authentication:’ and change to,

PermitLogin no

and also change to this, further down,

# Change to no to disable tunnelled clear test passwords
PasswordAuthentication no

Raspberry Pi Linux – Managing User Accounts

This information is available on the Rspberry Pi site here. I am just recapping for myself.

Change a user’s password

$ sudo passwd

Remove a user’s password

$ sudo passwd -d

Create a new user

$ sudo adduser

Remove a user,

$ sudo userdel -r

‘pi’ is a ‘sudoer’, which means this user can run as root when a command is preceded by ‘sudo’.
To switch to root,

$ sudo su

Add a user to ‘sudoers’,

$ sudo visudo

And add a line under ‘root ALL=(ALL:ALL) ALL’, eeplacing ‘root’ with e.g.,

ALL=(ALL:ALL) ALL

Raspberry Pi 3 Running noip2 systemd (part 9)

I find whenever the Pi has to reboot that I have to start noip2 each time with,

$ sudo noip2

This is exactly where systemd would be very useful. It would automatically restart the noip2 on boot or anytime it stops.

First we need to find where the noip2 binary is,

$ which noip2
/usr/local/bin/noip2

This is useful for finding the file that runs any command e.g

$ which ls
/bin/ls

Anyway, now we know that noip2 runs at /usr/local/bin/noip2. I would like to create a systemd service to run that binary file.

Create the file noip2.service at

/etc/systemd/system/noip2.service

[Unit]
Description=No-ip.com dynamic IP address updater
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target
Alias=noip.service

[Service]
# Start main service
ExecStart=/usr/local/bin/noip2
Restart=always
Type=forking

I obtained this file from Nathan Giesbrecht’s GitHub page.

Enable the service, so that it will start on boot.

$ sudo systemctl enable noip2.service

Then start it,

$ sudo systemctl start noip2.service

Sometimes it is necessary to also,

$ systemctl daemon-reload

Check the status of this new service with,

$ systemctl status noip2.service

To test it, reboot your Pi.

$ sudo reboot

Check that the noip2 is running automatically with,

$ ps -aux|grep noip2

The second line is I presume the process to run this command, so ignore it. The first line shows this process is running.

Raspberry Pi 3 Express Application (part 8)

Check Node and npm are installed,

$ node --version
v7.4.0
$ npm --version
4.0.5

Install Express generator globally,

$ npm install express-generator -g

Check it,

$ express --version
4.14.0

Create a new directory inside /opt/nodeserver

$ mkdir tempGraph

This will create several folders as well as the package.json file with all dependencies. Next install these dependencies,

$ sudo npm install

This automatically locates package.json in the same directory as the command is run in and installs them.

Start express with,

$ npm start

open another terminal on the same system and type,

$ curl localhost:3000

You should see same HTML,

Install nodemon to automatically restart application should it be updated, which will happen frequently during development.

$ npm install -g nodemon

To start nodemon, first top the application and be sure to be in the applications directory, then,

$ nodemon

Nodemon is for development not production.

Raspberry Pi 3 Crontab (part 7)

To run a file every 5 minutes we will use crontab,

$ crontab -e

And add the following to the bottom of that file, which opens with the ‘nano’ editor.

# m h dom mon dow command
*/5 * * * * python /opt/nodeserver/temperature.py # At every 5th minute
1 */1 * * * python /opt/nodeserver/temperatureHourlyAverages.py # At minute 1 past every hour
2 * */1 * * python /opt/nodeserver/temperatureDailyAverages.py # At minute 2 on every day-of-month

This data can be graphed using d3.js The file and graph are available at shanespi.no-ip.biz if the server is running at the time, that is. Next I want to run this with the Express backend framework as a systemd service.

Systemd could be used to run the python files instead of the crontab.