Edx – AngularJS: Advanced Framework Technique

Module 1. Code

Using Factory Singletons
To use a Factory, first declare it on your Angular app.

myApp.factory('thisFactory', function(){
    
})
You then set properties of the object that the factory is going to return.

myApp.factory('thisFactory', function(){
    var factoryObject = {};
    factoryObject.food = 'Chicken';
    factoryObject.drink = 'Soda';
    factoryObject.getAll = function(){
        return factoryObject.food + ' ' + factoryObject.drink;
    }

    return factoryObject;

})
If you do not want to share state between components, return a new instance of the object instead:

myApp.factory('thisFactory', function(){
    var factoryObject = {};
    factoryObject.food = 'Chicken';
    factoryObject.drink = 'Soda';
    factoryObject.getAll = function(){
        return factoryObject.food + ' ' + factoryObject.drink;
    }

    return new factoryObject;

})
In order to use your factory in your controller or directive, declare it as a dependency:

myApp.controller('myController', ['thisFactory', function(thisFactory){
    
}])
Then use the methods by accessing the subproperties of the factory as though it was a copy of the returned object you declared earlier.

myApp.controller('myController', ['thisFactory', function(thisFactory){
    var someFood = thisFactory.food;
    var someDrink = thisFactory.drink;
    var someOfAll = thisFactory.getAll();
}])

Current working

map.js

Source : Google map – https://github.com/carvemerson/map

https://github.com/mapsplugin/cordova-plugin-googlemaps-doc/blob/master/v2.0.0/README.md

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';
import { Geolocation } from '@ionic-native/geolocation';
import { LocationPage } from '../location/location';
import { AngularFireDatabase } from 'angularfire2/database';
import { NearbyProvider } from '../../providers/nearby/nearby';
import { GoogleMap, GoogleMaps, GoogleMapOptions, LatLng, GoogleMapsEvent, HtmlInfoWindow } from '@ionic-native/google-maps';

declare var google;

@Component({
  selector: 'page-map',
  templateUrl: 'map.html'
})
export class MapPage {
  @ViewChild('searchBar', { read: ElementRef }) searchBar: ElementRef;
  searchOpen: boolean = true;
  searchBox: any;
  query: string = '';
  @ViewChild('map') mapElement: ElementRef;

  map: GoogleMap;
  currentPosition: LatLng;
  currentMarker: any;
  places = [];
  infoWindow: HtmlInfoWindow<any>;
  placeService;

  constructor(private navCtrl: NavController, private geolocation: Geolocation, private db: AngularFireDatabase,
    private platform: Platform, private nearby: NearbyProvider, private googleMaps: GoogleMaps) {
      this.infoWindow = new HtmlInfoWindow();
  }

  toggleSearch() {
    this.searchOpen = !this.searchOpen;
  }

  ionViewDidLoad() {
    let latN, lngN;
    this.toggleSearch();
    const input = this.searchBar.nativeElement.querySelector('.searchbar-input');
    this.searchBox = new google.maps.places.SearchBox(input);
    this.searchBox.addListener('places_changed', () => {
      this.loadSearch();
    });
    this.geolocation.getCurrentPosition().then(position => {
      // Change to actual current location
      return new LatLng(position.coords.latitude, position.coords.longitude);
    }).catch(error => {
      // Default current position to vancouver
      return new LatLng(49.2827, -123.1207);
    }).then(latLng => {
      this.currentPosition = latLng;
      this.platform.ready().then(() => {
        let mapOptions: GoogleMapOptions = {
          camera: {
            target: {
              lat: this.currentPosition.lat,
              lng: this.currentPosition.lng
            },
            zoom: 17,
            tilt: 30
          }
        };
        
        this.map = this.googleMaps.create('map', mapOptions);
        this.placeService = new google.maps.places.PlacesService(new google.maps.Map(document.createElement('div')));

        this.map.one(GoogleMapsEvent.MAP_READY)
          .then(() => {
            this.map.addMarker({
              icon: 'assets/images/marker-current.png',
              draggable: true,
              position: {
                lat: latN ||this.currentPosition.lat,
                lng: lngN ||this.currentPosition.lng
              }
            })
            .then(marker => {
              marker.on(GoogleMapsEvent.MARKER_DRAG_END)
                .subscribe(() => {
                  latN = marker.getPosition().lat;
                  lngN = marker.getPosition().lng; 
                  console.log("Drag to new location");
                });
            });
            this.loadNearby();
          });
      });
    });
  }

  loadNearby() {
    this.placeService.nearbySearch({
      bounds: new google.maps.LatLngBounds(new google.maps.LatLng({lat: this.map.getVisibleRegion().southwest.lat, lng: this.map.getVisibleRegion().southwest.lng}), new google.maps.LatLng({lat: this.map.getVisibleRegion().northeast.lat, lng: this.map.getVisibleRegion().northeast.lng})),
      type: [this.nearby.getPlaceType()]
    }, (places, status, pagination) => {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        this.addMarkers(places);
        if (pagination.hasNextPage) {
          pagination.nextPage();
        }
      }
    });
  }

  loadSearch() {
    this.clearMarkers();
    let searchPlaces = this.searchBox.getPlaces();
    this.addMarkers(searchPlaces);
    if (this.places.length) {
      let bounds = new google.maps.LatLngBounds();
      this.places.forEach(place => {
        bounds.extend(place.geometry.location);
      });
      (<any> this.map).setBounds(bounds);
    };
  }

  clearMarkers() {
    for (var i = 0; i < this.places.length; i++) {
      if (this.places[i].marker) this.places[i].marker.remove();
    }
    this.places.length = 0;
  }

  addMarkers(places) {
    places.forEach(place => {
      this.db.object('/locations/' + place.place_id).valueChanges().take(1).subscribe(data => {
        place.reviewsAvg = data && data['reviewsAvg'] || 0;
        place.reviewsCount = data && data['reviewsCount'] || 0;
        place.marker = this.map.addMarker({
          icon: (place.reviewsAvg > 0 && place.reviewsAvg <= 2) ? 'assets/images/marker-alert.png' : 'assets/images/marker-default.png',
          position: {
            lat: place.geometry.location.lat(),
            lng: place.geometry.location.lng()
          }
        }).then(marker => {
          marker.on(GoogleMapsEvent.MARKER_CLICK)
            .subscribe(() => {
              this.infoWindow.close();
              this.infoWindow.setContent('<div><strong><a href="/#/home/map/location/' + place.place_id + '">' + place.name + '</a></strong><br>' +
                'Reviews: ' + place.reviewsCount + '<br>' +
                'Rating: ' + place.reviewsAvg + '<br>' +
                (place.formatted_address || '') + '</div>');
              this.infoWindow.open(marker);
            });
        });
        this.places.push(place);
      });
    });
  }
}

 

Getting camera position change

 

Ionic Draft UNSORT

  1. JSON filter and sorting
  2. AngularFireDatabase
  3. Getting key  Controlling back button to specific page
  4. From project folder pass these lines
  5. Tell Git who you are
    First, you need to tell Git who you are:

    git config –global user.email “you@example.com”
    git config –global user.name “Your Name”

    Give GitHub your public keys

    Some basic Git operations
    When we worked on GitHub, the basic work cycle was fork > edit > commit > pull request > merge. The same cycle, with a few differences, is what we will work through on the commandline.

    $ git status
    # On branch master
    nothing to commit (working directory clean)

  6. Connect n merge coder from dev to tenzin
  7. git checkout dev
    git pull
    git checkout tenzin
    git merge dev
  8. Connect and merge from tenzin to dev branch
    git checkout dev
    git merge t***
    git push
    git checkout t****
  9. To connect to new branch in remote we have to follow this step
    git pull
    git checkout team
    git pull
    git checkout ngodup
    git merge team

    9.git branch commands’ various options. -a shows all local and remote branches, while -r shows only remote branches.

    git branch -a
    git branch -r
    git branch -v -r
  10. There’s also another way to do figure out what branches are on your remote by actually using the remotely related commands, git remote and git ls-remote. The former displays plenty of information about the remote in general and how it relates to your own repository, while the latter simply lists all references to branches and tags that it knows about.
    $ git remote show origin
    $ git ls-remote --heads origin

JSON FILTER N SORTING

    this.data = this.http.get('/assets/json/drills.json').map(res => {
      return res.json().drillTypes.filter(item => {
        return item.activity == 'Tactic';
      }).map(item => {
        item.serial = Number(item.serial);
        return item;
      }).sort(function (v1, v2) {
        if (v1.serial < v2.serial) {
          return -1;
        } else if (v1.serial > v2.serial) {
          return 1;
        } else {
          return 0;
        }
      });
    });
<ion-content padding>
  <ion-card *ngFor="let item of data | async">
    <ion-item (click)="goDrill(item)">
      <ion-avatar item-start>
        <img *ngIf="item.isHand" src="../../../assets/hand.png">
        <img *ngIf="item.isRacquet" src="../../../assets/racquet.png">
      </ion-avatar>
      <h4>{{activity}} {{typeName}} {{serial}}<br/>{{item.type}} {{item.serial}}</h4>
      <button ion-button color="dark" clear item-right>
        <ion-icon name="arrow-forward"></ion-icon>
      </button>
    </ion-item>

    <ion-card-content>
      <div [innerHTML]="item.description"></div>
    </ion-card-content>
  </ion-card>
</ion-content>

 

ANGULARFIREBASE DATABASE GETTING KEY 

Add the code typescript


import { AngularFireDatabase } from 'angularfire2/database';
import { DrillPage } from '../drill/drill';


export class DrillListPage {

  drills: any;
  drillPage;
  
  constructor(public navCtrl: NavController, public navParams: NavParams, private db: AngularFireDatabase) {
    this.drillPage = DrillPage;

    this.drills = this.db.list('/drills').snapshotChanges().map(changes => {
      return changes.map(drill => ({ 
        key: drill.payload.key, 
        ...drill.payload.val() 
      }));
    });
  }

Add template for accessing key 

 <ion-list>
    <button ion-item *ngFor="let drill of drills | async" (click)="itemTapped($event, drill)">
      <ion-row>
          <ion-col col-11>
            <h2>Drill key - {{drill.key}}</h2>
              <h4>{{drill.type}} {{drill.serial}}</h4>
            <span [innerHTML]="drill.description"></span>
          </ion-col>
          <ion-col col-1>
              <ion-icon name="arrow-forward"></ion-icon>
          </ion-col>
        </ion-row>
    </button>
  </ion-list>

For Angulardatabase CRUD more information – https://github.com/codediodeio/angular-firestarter/blob/master/src/app/uploads/shared/upload.service.ts


  private deleteFileData(key: string) {
    return this.db.list('/drillstype').remove(key);
  }

 

CONTROLLING BACK BUTTON FOR SPECIFIC PAGE

  ionViewDidLoad() {
    this.navBar.backButtonClick = () => {
      let pages = [{
			  page: WelcomePage
		  }];
	    this.navCtrl.setPages(pages);
	}

 

Google map js

—- PROBLEM WITH GOOGLE MAP NATIVE FOR NEW LOCATION OR DRAG TO ADD NEW MARKER —

ADD MARKER

https://github.com/mapsplugin/cordova-plugin-googlemaps/issues/844

https://github.com/zyra/ionic-native-playground/blob/ionic-native-1577/src/pages/google-maps/google-maps.ts#L17-L29

https://github.com/ionic-team/ionic-native/issues/1577

Ionic Native Google Maps app example

 

——— WORKING CODE GOOGLE MAP JS FOR PLACE ID, CURRENT LOCATION ——

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';
import { Geolocation } from '@ionic-native/geolocation';
import { LocationPage } from '../location/location';
import { AngularFireDatabase } from 'angularfire2/database';
import { NearbyProvider } from '../../providers/nearby/nearby';

declare var google;

@Component({
  selector: 'page-map',
  templateUrl: 'map.html'
})
export class MapPage {night_club

  @ViewChild('searchBar', { read: ElementRef }) searchBar: ElementRef;
  searchOpen: boolean = true;
  searchBox: any;
  query: string = '';
  @ViewChild('map') mapElement: ElementRef;
  map: any;
  currentPosition: any;
  currentMarker: any;
  places = [];
  infoWindow: any;
  placeService;

  constructor(private navCtrl: NavController, private geolocation: Geolocation, private db: AngularFireDatabase, private platform: Platform, private nearby: NearbyProvider) {
  }

  toggleSearch() {
    this.searchOpen = !this.searchOpen;
  }

  ionViewDidLoad() {
    this.toggleSearch();
    const input = this.searchBar.nativeElement.querySelector('.searchbar-input');
    this.searchBox = new google.maps.places.SearchBox(input);
    this.searchBox.addListener('places_changed', () => {
      this.loadSearch();
    });
    this.geolocation.getCurrentPosition().then(position => {
      // Change to actual current location
      return new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
    }).catch(error => {
      // Default current position to vancouver
      return new google.maps.LatLng(49.2827, -123.1207);
    }).then(latLng => {
      this.currentPosition = latLng;
      this.platform.ready().then(() => {
        let mapOptions = {
          center: this.currentPosition,
          zoom: 17
        };
        this.infoWindow = new google.maps.InfoWindow();
        this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
        this.placeService = new google.maps.places.PlacesService(this.map);
        google.maps.event.addListenerOnce(this.map, 'tilesloaded', () => {
          this.currentMarker = new google.maps.Marker({
            icon: 'assets/images/marker-current.png',
            position: this.currentPosition,
            clickable: false,
            map: this.map
          });
          this.loadNearby();
        });
        google.maps.event.addListener(this.map, 'click', (event) => {
          if (event.placeId) {
            this.placeService.getDetails({placeId: event.placeId}, (place, status) => {
              if (status === 'OK') {
                this.db.object('/locations/' + event.placeId).valueChanges().take(1).subscribe(data => {
                  this.infoWindow.close();
                  this.infoWindow.setPosition(place.geometry.location);
                  if(data) {
                    this.infoWindow.setContent('<div><strong><a href="/#/home/map/location/' + place.place_id + '">' + place.name + '</a></strong><br>' +
                      'Reviews: ' + data['reviewsCount'] + '<br>' +
                      'Rating: ' + data['reviewsAvg'] + '<br>' +
                      (place.formatted_address || '') + '</div>');
                  } else {
                    this.infoWindow.setContent('<div><strong><a href="/#/home/map/location/' + place.place_id + '">' + place.name + '</a></strong><br>' +
                    'Reviews: 0<br>' +
                    'Rating: 0<br>' +
                    (place.formatted_address || '') + '</div>');
                  }
                  this.infoWindow.open(this.map);
                });
              }
            });
          }
          event.stop();
        });
      });
    });
  }

  loadNearby() {
    console.log('loadNearby', this.nearby.getPlaceType());
    this.placeService.nearbySearch({
      bounds: this.map.getBounds(),
      type: [ this.nearby.getPlaceType() ]
    }, (places, status, pagination) => {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        this.addMarkers(places);
        if (pagination.hasNextPage) {
          pagination.nextPage();
        }
      }
    });
  }

  loadSearch() {
    this.clearMarkers();
    let searchPlaces = this.searchBox.getPlaces();
    this.addMarkers(searchPlaces);
    if (this.places.length) {
      let bounds = new google.maps.LatLngBounds();
      this.places.forEach(place => {
        bounds.extend(place.geometry.location);
      });
      this.map.fitBounds(bounds)
    };
  }

  clearMarkers() {
    for (var i = 0; i < this.places.length; i++) {
      if (this.places[i].marker) this.places[i].marker.setMap(null);
    }
    this.places.length = 0;
  }

  addMarkers(places) {
    places.forEach(place => {
      this.db.object('/locations/' + place.place_id).valueChanges().take(1).subscribe(data => {
        place.reviewsAvg = data && data['reviewsAvg'] || 0;
        place.reviewsCount = data && data['reviewsCount'] || 0;
        place.marker = new google.maps.Marker({
          icon: (place.reviewsAvg > 0 && place.reviewsAvg <= 2) ? 'assets/images/marker-alert.png' : 'assets/images/marker-default.png',
          position: place.geometry.location,
          map: this.map
        });
        google.maps.event.addListener(place.marker, 'click', () => {
          this.infoWindow.close();
          this.infoWindow.setContent('<div><strong><a href="/#/home/map/location/' + place.place_id + '">' + place.name + '</a></strong><br>' +
            'Reviews: ' + place.reviewsCount + '<br>' +
            'Rating: ' + place.reviewsAvg + '<br>' +
            (place.formatted_address || '') + '</div>');
          this.infoWindow.open(this.map, place.marker);
        });
        this.places.push(place);
      });
    });
  }
}

Js Code to detect Mobile Device

Javascript code to determin mobile device

	if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
  alert("Hi mobile");
  }
else{
	alert("Hi desktop");
}

Javascript code to determine data Saver on|off in browser.

    if("connection" in navigator ){
        if (navigator.connection.saveData === true){
            alert("datasaver on");
        }else{
            alert("data saver is off");
        }
    }

Javascript code to determine chrome browser or not

if( navigator.userAgent.toLowerCase().indexOf('chrome') > -1 ){
	alert("chrome");
}else{
	alert("Not Chrome")
}

Javascript code to determine chrome version

function getChromeVersion () {     
    var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
    return raw ? parseInt(raw[2], 10) : false;
}
alert(getChromeVersion ());

 

Twig Basic

Concatenate two string in Twig

{% set c = a ~ b %}
{{ 'http://' ~ app.request.host }}

Not condition in twig

{% if not user.subscribed %}
    <p>You are not subscribed to our mailing list.</p>
{% endif %}

For multiple conditions, and and or can be used:

{% if temperature > 18 and temperature < 27 %}
      It's a nice day for a walk in the park.
{% endif %}

For multiple branches, elseif and else can be used like in PHP.

{% if kenny.sick %}
     Kenny is sick.
{% elseif kenny.dead %}
     You killed Kenny! You bastard!!!
{% else %}
     Kenny looks okay --- so far
{% endif %}

You can also test if an array is not empty:

{% if users %}
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
{% endif %}

Ionic Integrating Google Map SDK

In many of mobile apps and modern web app allow us to utilize different mapping features such as showing the current location, add a marker with text and creating routes. We can achieve this feature through the use of Google Map Cordova plugin.

In ionic we can use an abstract all mapping functions into a new <ion-map> directive and $ionicMap delegate. In last an example, we have Google map integration in Ionic through Javascript Google map library. Here in this example, we will integrate the Google map SDK in our ionic apps.

Step 1: Step up the project: 

ionic start googleMap blank

Step 2: Setting up Google Map API in Google Developer Console

In order to use the Google Maps API, you must register your application on the Google Developer Console and enable the API. To do this, start by going to the Google Developer Console for Google API for the map. If you already have a project created, you can skip the next section. If not, you can follow along and create a new project for your maps application. 
We need to enable the Google Maps SDK for iOS or the Google Maps Android API, or both. Let’s select the Google Maps SDK for an Android for this example. In the Google developer console find the API library and select Google Maps Android API and we have to enable the API. In the dashboard, we have to click on credential to create API key for our project and select key restriction for Andriod. For the android, we have specified the package name and SHA-1 certificate fingerprint. Copy package name from our AndroidManifest.xml file. We can generate SHA1 from the following command on cmd as

C:\Users\Username>keytool -exportcert -list -v -alias androiddebugkey -keystore .android/debug.keystore

Once we have specified both the project name and SHA-1. We can have to install Google map Cordova plugin and have to specify the API in for plugin.

ionic cordova plugin add cordova-plugin-googlemaps --variable API_KEY_FOR_ANDROID="Add your code"

npm install --save @ionic-native/google-maps



Resources

Free it book

  1. http://smtebooks.com/

Leaflet – leaflet d3js topojson

Best Buddhist Blog:
tinybuddha.com
lionsroar.com
tricycle.org
jackkornfield.com
leftbrainbuddha.com/the-blog/
buddhaweekly.com/
buddhism-controversy-blog.com

http://bl.ocks.org/tomschulze/961d57bd1bbd2a9ef993f2e8645cb8d2

Topojson on a leaflet map
http://bl.ocks.org/mpmckenna8/af23032b41f0ea1212563b523e859228

Updated December 6, 2016
d3 map with states and countries
http://bl.ocks.org/MaciejKus/61e9ff1591355b00c1c1caf31e76a668