Angular Template Website & Node API

Angular logo morphing into Nodejs illustrating Angular template website

This Angular template website began with the hopes of it being for this domain. But as we all know, development plans change.

There’s an onslaught of wonderful features loaded throughout. Features include but are not limited to:

  • All content is derived from a Node.js backend API with one default route (soon to be updated to a C# backend).
  • The API sends a JSON payload w/ 10 items per request.
  • Custom back button that works w/ query parameters.
  • Back button directive enabling placement of thereof on any page.
  • Notification when user clicks the browser back button.
  • Pagination, w/ query parameters (requests the next 10 from the API).
  • All payload data is then cached.
  • When the current page is selected, it’s checked against the cache.
  • API calls are only made if content doesn’t exist.
  • Page loader w/ CSS3 animation.
  • Modular categories. Meaning each top tier category has it’s own module and child routing.
  • Inbuilt shared module.
  • Each page has randomly generated categorically related content (thumbnails). This is a blog inspired feature where users are presented with additional reading options.
  • Six social media icons that appear either in the sidebar or after the content.
  • Pages have two different layout options that are easily configurable.
  • A media query service making screen sizes a breeze (ngIf=”screenSize > 728″).
  • Local storage interface.
  • Categories interface.
  • Local storage service.
  • Sidebar component
  • Color variables that can be imported anywhere.
  • Reset.css.
  • All category pages (pages w/ ten items and pagination) share the same style.
  • Method to easily access the window object.
  • A proxy that runs on an alternate port. This allow the API and UI to be run in tandem.
  • Config file w/ category names and a config service to broadcast it via a Behavior Subject.
  • All subscriptions are prepended w/ RxJS methods that unsubscribe.
  • Custom mobile animated fly out menu w/ burger icon.

Git Repo

Responsive Angular Template Website

There’s numerous breakpoints in place throughout the site. But these are the big ones housed in styles.scss. A feat which would undoubtedly be a nightmare w/ Bootstrap. I often build things like this to gain complete control over every detail. Style frameworks are good in my opinion for cookie cutter projects. And one in which you don’t mind if it looks like many other apps. Though this is an Angular template website, it’s the furthest things from conventional.

  • @media screen and (max-width: 1300px)
  • @media (min-width: 1200px) and (max-height: 700px)
  • @media only screen and (max-width: 1375px)
  • @media screen and (max-width: 1300px), screen and (max-height: 760px)
  • @media screen and (max-width: 1200px)
  • @media screen and (max-width: 992px)
  • @media screen and (max-width: 768px)
  • @media only screen and (max-width: 605px)
  • @media screen and (max-width: 500px)
  • @media screen and (max-width: 450px)

@media screen and (max-width: 1300px), screen and (max-height: 760px) is responsible for rearranging the UI when the height changes or the Dev Tools are opened.

Large header image with text and stacked related imagery.

There’s also of course scss files for most components. Styles are certainly shared and optimized wherever possible. The category styles for instance all share one sheet. Style color variables are also shared in _page-style.scss

Structural Directory

There’s three components in this directory. Header and footer component reside in app.module. The footer component just contains the copyright. Nothing else.

The header component contains the company logo as a base64 image. The Library and About links reside here in addition to the hamburger menu icon. Toggling the hamburger icon looks like this.

 constructor(
    private _globalFeatures: GlobalFeaturesService,
    private windowWidth: GlobalFeaturesService,
    public _sideBarService: SideBarService,
    private _renderer: Renderer2,
    @Inject(DOCUMENT) private document: Document
 ) {}
  
toggleMobileNav() {
    this.sidebarStatus = !this.sidebarStatus;
    if (this.sidebarStatus) {
      this._renderer.addClass(this.document.body, 'overflow-hidden');
      this._globalFeatures.scrollToTop();
    }
    if (!this.sidebarStatus) {
      this._renderer.removeAttribute(this.document.body, 'class');
    }
    this._sideBarService.changeValue(this.sidebarStatus);
  }

SidebarStatus sends a boolean to the sidebar service that toggles the menu. Renderer2 is being used here to control the hamburger icon.

Lastly is the right column component that serves as the sidebar. This is where the Leaflet map resides as well. Right-column.component.ts is where’d you change the location, zoom, and map tiles.

  private initializeMapOptions() {
    this.mapOptions = {
      center: latLng(36.168, -115.15),
      zoom: 13,
      layers: [
        tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
          maxZoom: 18,
          attribution: 'Map data © OpenStreetMap contributors'
        })
      ]
    };
  }

Angular Template Website Node Backend

The Node backend is not complex whatsoever. There’s a simple index file requiring Express and Helmet. It listens on a default port and uses routing. In the route, the function deciphers what category is being requested and filters the array of projects. In turn, only the chosen category is returned.

const port = process.env.PORT || 8080;

const express = require("express");
const app = express();
const helmet = require("helmet");

app.use(helmet());

app.use("/api/compliance-library", require("./routes/compliance-library"));

app.listen(port, (err) => {
  if (err) {
    console.log(err);
  } else {
    console.log(`listening on port ${port}`);
  }
});

module.exports = app;

In the UI, the amount is set to an increment of ten which increases every time new pagination is requested. The Express route receives this increment and in turn, returns the next group of ten. This route also handles category totals.

flow of data from UI to the API and where caching occurs.

Each time a request to the backend is made, the results are cached. What’s more, is that before the actual call is made, the cache is checked for the category AND for the selected group. For example, page one is selected, and there’s no cache — a request is made. If the user goes from page one to page three, it’s the same process. When the user returns to page one, a backend call is not made because the results are cached. A call is then made when page two is requested.

This is all made possible by setting up a Node API on the server. Node modules are installed on the server vs being uploaded directly. Additionally there’s several server configurations made followed by rigorous testing.

Running this locally requires a proxy.

// npm run start
"start": "ng serve --proxy-config proxy.conf.json",

// proxy.conf.json
"/api": {
   "target": "http://localhost:8080",
   "secure": false
}

// In an alternate terminal fire up the Node API
listening on port 8080

Conclusion

Embarking on this endeavor has been a challenging development process. With obstacles at every turn, it’s possible that building this has been more trying than most if not all other projects. Let’s be real. How often do we as devs get the opportunity to build a massive application entirely on our own? Test, modify, etc. To see more projects like this, view them here.

Regardless, I’m pleased it’s in a good place. One in which I can seamlessly add new features. Please see my other websites or a fully developed SPA. I hope you’ve enjoyed this explanation on this Angular template website.

1 Trackback / Pingback

  1. Website Examples - Frontend Dev

Leave a Reply

Your email address will not be published.


*