How to commit local project to git repository

Hi Guys, Iam not going into much theory on committing our existing project., Here is the straight forward flow through git commands

step 1: clearing .gitto overcome commit complications

rd .git /s/q
/* removing git directory */

Step 2: add all modified and new files in the current directory and all subdirectories to the staging area, thus preparing them to be included in the next git commit

git add .

Step 3: git init command., It can be used to convert an existing, unversioned project to a Git repository or initialize a new, empty repository

git init

Step 4: git commit. The “commit” command is used to save your changes to the local repository. Note that you have to explicitly tell Git which changes you want to include in a commit before running the “git commit” command using 'git add index.html', 'git add .'(adding all unstaged, modified files etc) This means that a file won’t be automatically included in the next commit just because it was changed.

git commit -m "your message"

/* enter message for your commit reference to easy unsderstanding commit details */

Step 5: git remote add origin https://github.com/yourRepositoryurl.gitcreates a new remote called origin located at https://github.com/yourrepositoryurl.git. Once you do this, in your push commands, you can push to origin instead of typing out the whole URL

git remote add origin https://github.com/repositoryurl

Step 6: git push origin master Git also uses origin as a system alias for pushing and fetching data to and from the primary branch. For example, git push origin master , when run on a remote, will push the changes to the master branch of the primary repository database.

git push origin master

Now you at4e good to go and check code in your repository

Advertisements

Polymer build with service worker in polymer 3

Hi guys., here is the step by step configuration steps on creating a polymer application build ready to deploy in tomcat server

defining base path:
“basePath”: “some/other/path”

/* it can be defined in polymer.json as above property or in you project folder index.html as follows*/

<base href="/path"&gt;

polymer.json specifications:

{
    "basePath": "some/other/path",
	/* defines base path of your project folder */
	"entrypoint": "index.html",
	/*most probably always be index.html., main file*/
	"shell": "src/polymerfirst-app/polymerfirst-app.js",
	/*path to your main app*/
	
	"sources": [
		"src/*/*.*",
		/*crawls though all files & folders inside src*/
		"package.json"
		/*for npm install... dont forget to define npm: true below*/
	],
	"extraDependencies": [
		/*these are basically the files we define in index.html which does not have import statement & all cache files etc*/
		"manifest.json",
		"node_modules/@webcomponents/webcomponentsjs/**",
		"node_modules/web-animations-js/web-animations-next-lite.min.js"
	],	
	"npm": true,
	/*to run npm install from package.json*/
	"builds": [
		{ 
			"name": "es5prod",
			"preset": "es5-bundled"
		},
		{ 
			"name": "es6prod",
			"preset": "es6-unbundled",
			"addServiceWorker": true
		}
		/*it can produce all bundles defined...*/
		/*addServiceWorker needs to be defined only for es6 build., as es5 by default creates service worker....*/
		/*no need to create service-worker.js file... it automatically creates on defining*/
		/*service worker works only on es6 bundle... need to make some manual fix for es5-bundle*/
	],
	"lint": {
		"rules": [
			"polymer-3"
		]
	}
	/*basically polymer 3 rules checkup*/
}

polymer 3 service worker needs to be called in index.html to check if service worker is requested and cache application

in index.html., write following code

if ('serviceWorker' in navigator) {
			// Delay registering until page load
			window.addEventListener('load', function() {
			  navigator.serviceWorker.register('service-worker.js');
			});
		}

Now., create sw-precache-config.js file in project root folder

in sw-precache-config.js., we need to define what all data needs to be cached to work in offline mode

note: service worker works well with es6-bundle but not with es5

module.exports = {
  staticFileGlobs: [
    'manifest.json',
	'node_modules/**/*',
    'src/**/*'
	/*basically all the files/templates required to cache for application to run*/
  ],
  runtimeCaching: [
    {
      urlPattern: /\/@webcomponents\/webcomponentsjs\//,
      handler: 'fastest'
    },
    {
      urlPattern: /^http:\/\/localhost:3000\/yourApiUrl/,
      handler: 'networkFirst'
	  /*By default,service worker only caches template.,for data to work along with that., we need to define network in sw-precache-config.js file as above*/
    }
  ]
};

Thats all., save this configuration and give polymer serve from your application. You are good to go ahead and make build.

How to create simple pagination with javascript in polymer 3

Hi Guys, In this tutorial iam gonna show how to create a simple pagination with prev & next buttons.

Step 1: Create a simple JSON.

{"transactionHistory":[
  {
    "user_id": 1,
    "details": [
      {
        "spend-category": "Travel",
        "amount": "123",
        "date": "2019-03-01",
        "payment-type": "make",
        "description": "sample test 1"
      }
    ],
    "id": 1
  },
  {
    "user_id": 1,
    "details": [
      {
        "spend-category": "Travel",
        "amount": "123",
        "date": "2019-03-03",
        "payment-type": "make",
        "description": "sample test 2"
      }
    ],
    "id": 2
  }
]
}
** create set of json objects ... take atleast 15 records for better pagination view **

Step 2: Make an API call to get JSON obj

$http.get('http://localhost:3000/transactionHistory').then();

then() triggers when request results is received.
Now assign the response to a variable

$http.get('http://localhost:3000/transactionHistory').then(function(data){
  this._getAllResults();
});
_getAllResults(){
   this.resData = data.transactionHistory;
}

Now Iam going to show only 3 records per page by passing start, end array values in slice() method

code step 1: check slice working

$http.get('http://localhost:3000/transactionHistory').then(function(data){
   this._getAllResults();
 });

_getAllResults(event){
   this.resData = data.transactionHistory;
   let start, end;
   start = 0;
   end = 3;
   this.filteredResults = this.resData.slice(start,end);
}

** slice() accepts 2 parameters **
  - start: array index start value
  - end: Array index end value

Creating <dom-repeat> template to render results

<table class="table mt-5">
    <thead>
        <tr>
            <th>Transaction ID</th>
            <th>Transaction Date</th>
            <th>Transaction Amount</th>
            <th>Transaction Type</th>
            <th>Comments</th>
        </tr>
    </thead>
    <tbody id="scrollable-element" style="overflow: auto;height: 200px;">
        <template scroll-target="scrollable-element" is="dom-repeat" items=[[filteredResults]]>
					<template is="dom-repeat" items=[[item.details]]  as="historyResults">
						<tr>
							<td scope="row">{{item.id}}</td>
							<td>{{historyResults.date}}</td>
							<td>{{historyResults.amount}}</td>
							<td>{{historyResults.payment-type}}</td>
							<td>{{historyResults.description}}</td>
						</tr>
					</template>
        </template>
    </tbody>
</table>

Now., Create 2 buttons previous & Next with
onclick
function

<paper-button raised on-click="_getAllResults">Previous</paper-button>
<paper-button raised on-click="_getAllResults">Next</paper-button>

_getAllResults will trigger pagination

Now set a properties for inital declaration of pageNumber which later will be incremented

static get properties(){
        return {
            pageNumber: {
                type: Number,
                value: 0
            }
        }
    }

Now., on clicking next button., start and end must increment by 3 each. Here is the logic for that

Click Button: next

_getAllResults(event){
	this.resData = data.transactionHistory;
	let start, end
	start = 0;
	end = start + 3;
	   /* During initial load., there wont be any button click event., but on clicking next button., event gets triggered */
	if(event){
		switch(event.target.innerHTML){
			case 'Next':
				this.pageNumber++;
				start = this.pageNumber * 3;
				end  = start + 3;
				/* this.pageNumber increments to 1.,  */
				/* start: 1*3 = 3  */
				/* end 3 + 3  = 6  */
				/* This above values get appended to this.resData slice method */
		}
		 
		
	}
   this.filteredResults = this.resData.slice(start,end);
}

Click Button: Prev

_getAllResults(event){
	this.resData = data.transactionHistory;
	let start, end
	start = 0;
	end = start + 3;
	/* Initial declaration of start, end is for before next & previous button click event */
	   /* During initial load., there wont be any button click event., but on clicking next button., event gets triggered */
	if(event){
		switch(event.target.innerHTML){
			case 'Next':
				this.pageNumber++;
				start = this.pageNumber * 3;
				end  = start + 3;
				break;
				/* this.pageNumber increments to 1.,  */
				/* start: 1*3 = 3  */
				/* end 3 + 3  = 6  */
				/* This above values get appended to this.resData slice method */
			case 'Prev':
				this.pageNumber--;
				start = this.pageNumber * 3;
				end  = start + 3;
				break;
				/* this.pageNumber decrements to 0.,  */
				/* start: 0*3 = 0  */
				/* end 0 + 3  = 3  */
				/* This above values get appended to this.resData slice method */	
		}
		 
		
	}
   this.filteredResults = this.resData.slice(start,end);
}

Disabling prev and next button when array length is less/greater

Create disabled property on buttons

<paper-button raised disabled="[[isPrevDisabled]]" on-click="_getAllResults">Previous</paper-button>
                    <paper-button raised disabled="[[isNextDisabled]]" on-click="_getAllResults">Next</paper-button>

Checking diabled property in results rendering

_getAllResults(event){
	this.resData = data.transactionHistory;
	this.isPrevDisabled = true;
    this.isNextDisabled = false;
	/* disbaling rev button on first load since there are no records before 0 index */
	let start, end
	start = 0;
	end = start + 3;
	/* Initial declaration of start, end is for before next & previous button click event */
	   /* During initial load., there wont be any button click event., but on clicking next button., event gets triggered */
	if(event){
		switch(event.target.innerHTML){
			case 'Next':
				this.pageNumber++;
				start = this.pageNumber * 3;
				end  = start + 3;
				this.isPrevDisabled = false;
				/* Disabling prev false as it enters next page */
                this.isNextDisabled = end > this.responseArray.length ? true : false;
				/* enabling next button till it reaches response array ength using ternanry opearator */
				break;
				/* this.pageNumber increments to 1.,  */
				/* start: 1*3 = 3  */
				/* end 3 + 3  = 6  */
				/* This above values get appended to this.resData slice method */
			case 'Prev':
				this.pageNumber--;
				start = this.pageNumber * 3;
				end  = start + 3;
				this.isPrevDisabled = this.pageNumber === 0 ? true : false;
				/* Disabling prev if enters response array length 0 */
                this.isNextDisabled = false;
				/* Enabling Next as it is still in array length */
				break;
				/* this.pageNumber decrements to 0.,  */
				/* start: 0*3 = 0  */
				/* end 0 + 3  = 3  */
				/* This above values get appended to this.resData slice method */	
				default:
                    start = 0;
                    end = start + 3;
                    break;        
				/* setting defaults for array slice start and end */	
		}
		 
		
	}
   this.filteredResults = this.resData.slice(start,end);
}

How to handle params in app-route using subRoute in polymer 3

Hi Guys, I was having a requirement to show products list and on-click of product., I have to redirect the user to details page with product ID and sub ID as params in router using app-route in polymer 3.

Here is the process I have implemented to pass params in app-route

Step 1: Define app-route in your application main-app

<app-route
          route="{{route}}"
          pattern="/:page"
          data="{{routeData}}"
          tail="{{subroute}}">
</app-route>

Here Iam defining products-list page, products details page under iron-pages

<iron-pages selected="[[page]]" attr-for-selected="name" selected-attribute="visible">
        <products-overview name="overview"></products-overview>
        <prodcut-details name="details"></prodcut-details>
</iron-pages>

Here, in product overview page, iam trying to load some products looping through JSON. Below eg json and products overview grid.

/* sample json */

"products": [
    { "id": 1, 
      "title": "Sample Product 1", 
      "subproducts": [
        {"sub_id": 1, "productName":"First sub Product 1"},      
        {"sub_id": 2, "productName":"First sub Product 2"},      
        {"sub_id": 3, "productName":"First sub Product 3"}      
      ] 
    },
    { "id": 2, 
      "title": "Sample Product 2", 
      "subproducts": [
        {"sub_id": 1, "productName":"First sub Product 1"},      
        {"sub_id": 2, "productName":"First sub Product 2"},      
        {"sub_id": 3, "productName":"First sub Product 3"}      
      ] 
    }
]

In ready state (ready()): write an ajax call to make API call and get response and add it to `data` 

ready(){
        super.ready();
        let ajaxCall = this.$.ajax;
        ajaxCall.url = "http://localhost:3000/products";
        ajaxCall.generateRequest();
    }
    handleResponse(event){
        this.data = event.detail.response;
    }

Received products list can be rendered in HTML in below format
/* for making ajax call */
<iron-ajax
            id="ajax"
            handle-as="json"
            on-response="handleResponse"
            debounce-duration="300">
</iron-ajax>

/* looping through json and adding it to drop down accordian to show products & sub products */
<vaadin-accordion>
            <template is="dom-repeat"  items="{{data}}" as="product">
                <vaadin-accordion-panel theme="filled"> 
                    <div slot="summary">{{product.title}}</div>
                    <template is="dom-repeat" items="{{product.subproducts}}">
<!-- ON clicking of a product., it redirects to details page carrying its `id` and `sub_id`
                        <div><a href="/details/[[product.id]]/[[item.sub_id]]">{{item.productName}}</a></div>
                    </template>  
                </vaadin-accordian-panel> 
            </template>
</vaadin-accordion>

/* the params we are sending (/[[product.id]]/[[item.sub_id]]) are basically params which can be tracked in ** tail ** of <app-route> (i.e. tail={{subRoute}}) */

Now the data available in tail needs to be binded to product-details.js page by passing as a property in component as below

<iron-pages selected="[[page]]" attr-for-selected="name" selected-attribute="visible">
        <prodcut-details name="details" route={{subroute}}></prodcut-details>
</iron-pages>

/* route={{subroute}} : `subroute`  is the data captured in `tail` attribute in <app-route> defined in main-app.js 
*/

code below

<app-route
         tail="{{subroute}}">
</app-route>

Now., in the above code., `/details/[[product.id]]/[[item.sub_id]]”>{{item.productName}}` carries product id and sub id to details page.,

Now as per above <a> tag., it is not using switch case defined in main-app(u can see its details here) … it directly loads details page.,

hence we need to define <app-route> in details page as well to capture tail data as explained above.

Step 2: prodcut-details.js

In product-details.js., the data captured in tail needs to be captured back in product-details.js (hence we need to define <app-route> in product-details.js) as well.

**  in product-details.js page **

<app-route
            route="{{route}}"
            pattern="/:mainId/:subId"
            data="{{routeData}}">
</app-route>

/* note in route={{route}} actually need to capture URL params as data binding. hence we need to pass {{route}} data (i.e. params data)*/

/* after capturing data in route="{{route}}"., we need to define pattern for retrieving mainID & subID in its pattern which further be used to make API calls for data  ( pattern="/:mainId/:subId" )*/
/* data={{routeData}} has all route data along with its params */

/* now in ready state., just console.log(this.routeData.mainId, this.routeData.subId)., you can see params data */ 

Ag Grid with Accordian in polymer 3

Hi, here is the complete guide on implementing multi array json data to display on ag grid with accordian.

Step 1: Required imports

In order to implement Ag grid in polymer., you need to install ag grid through npm install from below command.


npm install ag-grid-community ag-grid-polymer --save

After installation., import that ag-grid in your polymer component

import 'ag-grid-polymer';

Now., we are creating a mock json and calling it in constructor to load in ag-grid

constructor(){

this.rowData = 

[
   {
      JsonData:'Json Data1',
      detail1:'10-12 years',
      detail2:'4000/month',
      detail3:'10 Lakh',
      details:[
         {
            group:'Json1.sub1',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json1.sub2',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json1.sub3',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         }
      ]
   },
   {
      JsonData:'Json Data',
      detail1:'10-12 years',
      detail2:'4000/month',
      detail3:'10 Lakh',
      details:[
         {
            group:'Json2.sub1',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json2.sub2',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json2.sub3',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         }
      ]
   },
   {
      JsonData:'Json Data3',
      detail1:'10-12 years',
      detail2:'4000/month',
      detail3:'10 Lakh',
      details:[
         {
            group:'Json3.sub1',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json3.sub2',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json3.sub3',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         }
      ]
   },
   {
      JsonData:'Json Data4',
      detail1:'10-12 years',
      detail2:'4000/month',
      detail3:'10 Lakh',
      details:[
         {
            group:'Json4.sub1',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json4.sub2',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json4.sub3',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         }
      ]
   }
];
}

Now define., columnDefs (headers) for ag grid

// field value should match the json obj ID

this.columnDefs = [
      {headerName: "Json Data", field: 'Json', cellRenderer:'agGroupCellRenderer'},
      {headerName: "Details 1", field: "detail1"},
      {headerName: "Details 2", field: "detail2"},
      {headerName: "Details 3", field: "detail3"}
    ];

Now, create grid options in `constructor` to show data, filters and other available options

/* 
paginationpage size can also be automated based on json length by declaring autopagination to `true`.

Defining auto pagination will override paginationPageSize property

getNodeChildDetails: this is used to display accordian to expand/collapse child nodes

onCellClicked: used to get celldetails, row details etc
*/

this.getAllGridOptions = {
      defaultColDef:{
        sortable: true,
        filter: true,
        resizable: true,
        scrollable: true
        
      },
      paginationPageSize: 4,
      rowSelection: 'multiple',
      enableRangeSelection: true,
      pagination: true,
      getNodeChildDetails: this.getNodeChildDetails,
      onCellClicked: this.getRowDetails,
      onGridReady: function(params) {
      }
      
    };

getNodeChildDetails(rowItem) {
  if (rowItem.details) {
    return {
      group: true,
      expanded: rowItem.JsonData === 'Json Data1',
        // open Json Data1 be default
        children: rowItem.details,
        // the key is used by the default group cellRenderer
        key: rowItem.JsonData
    };
  } else {
      return null;
  }
}
// to get row details of clicked cell
getRowDetails(event){
  console.log(event.data);
}

Now in `static get template` method., call ag-grid in below format

<ag-grid-polymer
        id="rowGrid"
        gridOptions={{getAllGridOptions}} 
        class="ag-theme-balham" 
        rowData="{{rowData}}" 
        columnDefs="{{columnDefs}}" 
</ag-grid-polymer&gt;

See full code Below

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';
import 'ag-grid-polymer';
/**
 * @customElement
 * @polymer
 */
class aggridApp extends PolymerElement {
  constructor() {
    super();
    this.getAllGridOptions = {
      defaultColDef:{
        sortable: true,
        filter: true,
        resizable: true,
        scrollable: true
        
      },
      paginationPageSize: 4,
      rowSelection: 'multiple',
      enableRangeSelection: true,
      pagination: true,
      getNodeChildDetails: this.getNodeChildDetails,
      onCellClicked: this.getRowDetails,
      
    };
    this.columnDefs = [
      {headerName: "Json Data", field: 'JsonData',cellRenderer:'agGroupCellRenderer'},
      {headerName: "Details 1", field: "detail1"},
      {headerName: "Details 2", field: "detail2"},
      {headerName: "Details 3", field: "detail3"},
 ];
    
    this.rowData = 
   [
   {
      JsonData:'Json Data1',
      detail1:'10-12 years',
      detail2:'4000/month',
      detail3:'10 Lakh',
      details:[
         {
            group:'Json1.sub1',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json1.sub2',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json1.sub3',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         }
      ]
   },
   {
      JsonData:'Json Data',
      detail1:'10-12 years',
      detail2:'4000/month',
      detail3:'10 Lakh',
      details:[
         {
            group:'Json2.sub1',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json2.sub2',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json2.sub3',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         }
      ]
   },
   {
      JsonData:'Json Data3',
      detail1:'10-12 years',
      detail2:'4000/month',
      detail3:'10 Lakh',
      details:[
         {
            group:'Json3.sub1',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json3.sub2',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json3.sub3',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         }
      ]
   },
   {
      JsonData:'Json Data4',
      detail1:'10-12 years',
      detail2:'4000/month',
      detail3:'10 Lakh',
      details:[
         {
            group:'Json4.sub1',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json4.sub2',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         },
         {
            group:'Json4.sub3',
            detail1:'details1',
            detail2:'detail2',
            detail3:'detail3'
         }
      ]
   }
];
}
ready(){
  super.ready();
}
getNodeChildDetails(rowItem) {
  if (rowItem.details) {
    return {
      group: true,
      expanded: rowItem.policy === 'Json Data1',
        // open Json Data1 be default
        children: rowItem.details,
        // the key is used by the default group cellRenderer
        key: rowItem.JsonData
    };
  } else {
      return null;
  }
}
getRowDetails(event){
  console.log(event.data);
}
  static get template() {
    return html`
    <link rel="stylesheet" href="../../node_modules/ag-grid-community/dist/styles/ag-grid.css"&gt;
    <link rel="stylesheet" href="../../node_modules/ag-grid-community/dist/styles/ag-theme-balham.css"&gt;
      <style&gt;
        :host {
          display: block;
        }
      </style&gt;
      <h2&gt;Hello [[prop1]]!</h2&gt;
      <ag-grid-polymer
        id="rowGrid"
        gridOptions={{getAllGridOptions}} 
        style="width: 100%;" 
        class="ag-theme-balham" 
        rowData="{{rowData}}" 
        columnDefs="{{columnDefs}}" 
      </ag-grid-polymer&gt;
    `;
  }
  static get properties() {
    return {
      prop1: {
        type: String,
        value: 'Ag Grid'
      }
  } 
}

window.customElements.define('aggrid-app', aggridApp);

Polymer 3 Setup & Running

Hi Guys., recently I have done a work around on polymer 3. Since I don`t see any proper documentation on implementation for same., here the complete guide on how to setup working environment for polymer 3

Lets start with Polymer Installation.

  • In order to Install Polymer CLi globally on your system
    • Create a folder in your system for polymer workspace-> Open cmd -> navigate to polymer workspace path -> run below command
    • `npm install -g polymer-cli`
      • Note: You need to have Node JS Installed in your system
      • Note: Set environment variables for NPM
    •  After successful installation., check polymer running on your system use this command :
      • polymer --version
    • A complete set of guide is available here https://polymer-library.polymer-project.org/3.0/docs/install-3-0
  • Download Polymer 3 Application
    • To download polymer 3 application., go to your workspace folder -> Run command: polymer init
      • Select Polymer 3 Appplication
    • It asks for certail project name, descrtiption etc., enter details as your wish and click enter
    • It installs polymer 3 application along with npm installation
    • Post installation., you can see a project structure like this
    • In above folder structure.,
      • node_modules: consists of all NPM packages you install for this application
      • src: contains your project code. (should have one main component & rest all sub components)
        • Main component is called inside index.html
      • test: This contains all test cases written for this project
      • package.json: This is meta of NPM packages installed. We can see all dependencies, Dev Dependencies etc
  • Polymer 3 application Running:
    • In order to run polymer 3 application up and running.,
      • go to parent project folder in cmd prompt -> Run command: polymer serve
      • It takes 5 – 10 seconds to up and gives local server URL.

 

Well., That is basic requirement for polymer 3 setup & running in local environment.

Next Steps: How to create first custom element in polymer 3. Refer Here

How to implement routing in Polymer 3 using App Route

Hi Guys., recently I have done a work around on Implementing Routing in polymer 3. Since I don`t see any proper documentation on implementation for same., here the complete guide on how to Implement routing in Polymer 3.

If you are looking for polymer 3 setup environment up and running., Click here

Step 1:

Libraries Required for Polymer 3 Routing:

  • App-Route: App Route is a web component provided for polymer to implement routing. Download & configuration can be seen here.
  • Iron-Pages: Iron pages is basically a content switcher.
    • App-Route generally passes the URL requests., but content can`t be switched as single page application unless we wrap child components (pages e.g. About, Contact Us etc) inside Iron-Pages. Download & configuration can be seen here

Step 2:

Pages Creation (Components Creation):

  • In your `src` folder., create few components (pages)
    • home-comp.js
    • about-comp.js
    • contact-comp.js
  • Here I will show component code for one page., you can copy the same components with component name change accordingly
  • Here is the code for home-comp.js

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';

class homeComp extends PolymerElement{
	static get properties() {
		
	}
	static get template(){
		
		return html `
			<p>This page consists of Home Content</p>	
		`
	}
}
customElements.define('home-comp',homeComp);

/* Define component name with no capital letters in first param and camel case in 2nd param (2nd param should be same as class name)*/

  • Repeat same for about-comp.js, contact-comp.js with component name change

Step 3:

Setting up Router in main app

  • Install App-route, Iron-pages as shown in link provided above & import those in main component. In my case., polymerrouting-practice.js as follows
import '@polymer/app-route/app-location.js';
import '@polymer/app-route/app-route.js';
import '@polymer/iron-pages/iron-pages.js';
  • In static get template() method., define app-route for routing & iron-pages for content switching as follows
static get template() {
    return html`
      <style>
        :host {
          display: block;
        }
      </style>
        <app-location route="{{route}}"></app-location>
// routeDate - takes whole route, page - passes requested url
	  <app-route route="{{route}}" pattern="/:page" data="{{routeData}}" tail="{{subroute}}"></app-route>
	<ul>
	    <li>
		<a href="/home">Home</a>
	    </li>
	    <li> 
                <a href="/about">About</a> 
            </li>
	    <li> 
                <a href="/contact">Contact</a> 
            </li>
	</ul>
	  <iron-pages selected="[[page]]" attr-for-selected="name" selected-attribute="visible" fallback-selection="404">
		<home-comp name="home"></home-comp>
		<about-comp name="about"></about-comp>
		<contact-comp name="contact"></contact-comp>
	  </iron-pages>
    `;
  }
  • get page properties in static get properties() method
static get properties() {
    return {
	  page:{
		  type: String,
		  observer: '_pageChanged'
	  }
    };
  }
/* 
type: defines type of value it expects
reflectToAttribute: setting `true` will trigger whenever attribute changes occur
observer: it`s a simple observer., which triggers function whenever change occur in page property. hence on requesting URL., simple observer triggers
*/
  • Defining Complex observer: On first time app-loadin., page attribute returns undefined in old., page. A simple observer triggers only any changes happens to the properties defined. Hence a complex observer is required to trigger any changes happens to app (including page load). Hence complex triggers is required to define to observe changes on first time page load.
static get observers(){
	  console.log("test observer");
	return ['_routerChanged(routeData.page)'];
}
_routerChanged(page){
	console.log('CHANGED PAGE - ', page);
	this.page = page || 'home';
}

/*

Complex observer triggers on any changes in component. It is required to observe/set current page
*/
  • Writing switch cases for observer to track previous page and current page and import component accordingly
/* this pagechanged triggers for simple onserver written in page properties written above */
_pageChanged(currentPage, oldPage){
	  console.log('CURRENT - ', currentPage);
	  console.log('OLD - ', oldPage);
	  switch(currentPage){
		  case 'home':
			import('./home-comp.js').then()
			break;
		case 'about':
			import('./about-comp.js').then()
			break;
		case 'contact':
			import('./contact-comp.js').then()
			break;
		default:
			this.page = 'home';
	  }
  }
  • This basically can be considered as lazy loading to load components on demand
  • here is the complete code below
import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';
import '@polymer/app-route/app-location.js';
import '@polymer/app-route/app-route.js';
import '@polymer/iron-pages/iron-pages.js';
/**
 * @customElement
 * @polymer
 */
class polymerroutingPractice extends PolymerElement {
	constructor(){
		super()
	}
  static get template() {
    return html`
      <style>
        :host {
          display: block;
        }
      </style>
        <app-location route="{{route}}"></app-location>
// routeDate - takes whole route, page - passes requested url
	  <app-route route="{{route}}" pattern="/:page" data="{{routeData}}" tail="{{subroute}}"></app-route>
	<ul>
	    <li>
		<a href="/home">Home</a>
	    </li>
	    <li> 
                <a href="/about">About</a> 
            </li>
	    <li> 
                <a href="/contact">Contact</a> 
            </li>
	</ul>
	  <iron-pages selected="[[page]]" attr-for-selected="name" selected-attribute="visible" fallback-selection="404">
		<home-comp name="home"></home-comp>
		<about-comp name="about"></about-comp>
		<contact-comp name="contact"></contact-comp>
	  </iron-pages>
    `;
  }
  static get properties() {
    return {
	  page:{
		  type: String,
		  reflectToAttribute: true,
		  observer: '_pageChanged'
	  }
    };
  }
  static get observers(){
	  console.log("test observer");
	return ['_routerChanged(routeData.page)'];
  }
  
  _routerChanged(page){
	  console.log('CHANGED PAGE - ', page);
	  this.page = page || 'about';
  }
  
  _pageChanged(currentPage, oldPage){
	  console.log('CURRENT - ', currentPage);
	  console.log('OLD - ', oldPage);
	  switch(currentPage){
		  case 'home':
			import('./home-comp.js').then()
			break;
		case 'about':
			import('./about-comp.js').then()
			break;
		case 'contact':
			import('./contact-comp.js').then()
			break;
		default:
			this.page = 'home';
	  }
  }
}

window.customElements.define('polymerroutingpractice-app', polymerroutingPractice);

Next steps: How to handle params in app-route? click here

Hope this helps. Any questions., please comment below