Skip to content

Instantly share code, notes, and snippets.

@appsdevpk
Last active October 12, 2020 08:13
Show Gist options
  • Save appsdevpk/252541a50fcf8dfdb3e079adee01e1ce to your computer and use it in GitHub Desktop.
Save appsdevpk/252541a50fcf8dfdb3e079adee01e1ce to your computer and use it in GitHub Desktop.
Custom web component for fetching and displaying remote data using handlebars templates
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Remote Fetch Component</title>
<style>
.adp-remotefetch{
position: relative
}
#loader{
position:absolute;
width:100%;
height:100%;
text-align:center;
line-height:40%
}
</style>
</head>
<body>
<div id="loader">Loading</div>
<adp-remotefetch url="https://jobs.github.com/positions.json?description=javascript" params='{"page":1}' proxy="https://cors-anywhere.herokuapp.com/">
<template>
<ul>
{{#each this}}
<li>
<h3>{{ title }}</h3>
<p><img class="companylogo" src="{{ company_logo }}" alt="{{ title }}" /></p>
<p><strong>Type :</strong> {{ type }}</p>
<p><strong>Company :</strong> {{ company }}</p>
<p><strong>Website :</strong> {{ company_url }}</p>
<p><strong>Location :</strong> {{ location }}</p>
<p><strong>Description :</strong> <br />{{{ description }}}</p>
<a href="{{ how_to_apply }}">Apply for Job</a><br />
<a href="{{ url }}" class="viewmore">View Detail</a><br />
</li>
{{/each}}
</ul>
<style>
.companylogo{
width:150px;
}
</style>
</template>
</adp-remotefetch>
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script src="script.js"></script>
</body>
</html>
class AdpRemoteFetch extends HTMLElement{
constructor(){
super();
this.shadow = this.attachShadow({mode: 'open'});
this.containerDiv = document.createElement('div');
this.shadow.appendChild(this.containerDiv);
}
get url(){
return this.getAttribute('url');
}
set url(val){
if(val){
this.setAttribute('url',val);
this.updateContents();
}
}
get params(){
return this.getAttribute('params');
}
set params(val){
if(val){
this.setAttribute('params',val);
this.updateContents();
}
}
connectedCallback(){//one of the lifecycle callbacks
this.updateContents();
}
disconnectedCallback(){
console.log('Custom square element removed from page');
}
adoptedCallback(){
console.log('Custom square element moved to new page');
}
updateContents(){
const currElem = this;
const remoteLink = currElem.getAttribute('url');
const params = currElem.getAttribute('params');
const proxyurl = currElem.hasAttribute('proxy') ? currElem.getAttribute('proxy') : '';
var url = new URL(proxyurl + remoteLink);
if(params!==''){
url.search = new URLSearchParams(JSON.parse(params)).toString();
}
this.showLoader();
fetch(url,{cache: "force-cache"})
.then(response => response.json())
.then(data => {
const source = currElem.getElementsByTagName('template')[0].innerHTML;
const template = Handlebars.compile(source);
const html = template(data);
let containerDiv1 = document.createElement('div');
containerDiv1.innerHTML = html;
this.shadow.innerHTML = html;
this.hideLoader();
});
}
showLoader(){
document.getElementById('loader').style.display = 'block';
}
hideLoader(){
document.getElementById('loader').style.display = 'none';
}
}
customElements.define('adp-remotefetch',AdpRemoteFetch);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment