Getting Started with Firebase Cloud Firestore: Build a Vue Contact App

By Yomi Eluwande

Sometime back in October, Google announced the beta release of Firebase’s Cloud Firestore which is a fully-managed NoSQL document database for both mobile and web app development. Firestore was designed to easily store and sync your app’s data at global scale.

Cloud Firestore includes features such as:

  • Documents and collections with powerful querying
  • iOS, Android, and Web SDKs with offline data access
  • Real-time data synchronization
  • Automatic, multi-region data replication with strong consistency
  • Node, Python, Go, and Java server SDKs

In this tutorial, I will demonstrate how to get started with Firebase Cloud Firestore and also highlight the differences between Cloud Firestore and the existing Firebase Realtime Database.

We’ll be building a Contact Management app, it’s a basic CRUD app and Cloud Firestore acts as the backend database. You’ll be able to see all contacts, add a new contact and view an individual contact. The Contact Management app will be built using Vue.js.

A screenshot of the contact management app can be seen below and you can check out a live demo here.

To get started with the app, we’ll be using vue-cli to quickly scaffold a Vue.js app and even more specifically, the webpack template will be used.

Open a terminal window and run the following command to install the vue-cli tool:

npm install -g vue-cli

Let’s now create the Vue.js app, Run the following command in a working directory:

vue init webpack firestore

This will go ahead and create a folder titled firestore containing a working Vue.js app with features like Hot Module Reloading, Webpack and vue-loader for single file components, and routes.
Navigate to the firestore folder and run the npm run dev command to see the app live at http://localhost:8080.

Setting up Cloud Firestore

To begin using Firestore, you’ll need a Gmail account, once that’s good to go, you can sign in to https://console.firebase.google.com and create a new project.

You should get a dashboard similar to the one below. This dashboard contains all of Firebase’s other services that can be used in your application.

Click on “Add Firebase to your web app” and copy the config details specific to your project to a safe location as you’ll be needing it later.

Under the Develop menu, click on the Database link and under the database tab, click “Try Firestore Beta” and “Start in Test Mode”. That should take you to a dashboard where you can view the database as it changes in real time.

With Firestore, we’ll be dealing with documents and collections. Data is usually stored in documents, documents are stored in collections. A document may contain a collection and a collection may contain a document.

Vue.js and Firestore

Let’s get back to coding. Open the components folder and create two JavaScript files in it; firebaseConfig.js and firebaseInit.js.
The firebaseConfig.js file will contain the config values gotten from the Firebase dashboard, we’ll be exporting so it can be used in other locations.

export default {
  apiKey: 'AIzaSyDr0-Mef6D1RZsD2NoBaPOwordhUW58MyU',
  authDomain: 'contacts-app-dca62.firebaseapp.com',
  databaseURL: 'https://contacts-app-dca62.firebaseio.com',
  projectId: 'contacts-app-dca62',
  storageBucket: 'contacts-app-dca62.appspot.com',
  messagingSenderId: '715354469790'
}

We have a Firebase config file, but we need to initialize it somewhere, we can do that in the firebaseInit.js file like this:

import firebase from 'firebase'
import 'firebase/firestore'
import firebaseConfig from './firebaseConfig'
const firebaseApp = firebase.initializeApp(firebaseConfig)
export default firebaseApp.firestore()

In the code block above, firebase and firestore were both imported, as well as the firebaseConfig.js file created earlier. The config file is used to initialize Firebase in the project and is also exported with the firestore function.

Let’s create the different components that will be used for the app. We’ll be needing Home.vue, NewContact.vue and ViewContact.vue components. You can go ahead and create these files in the components folder.

Before we edit each component, let’s update the router file to accommodate these new components. Navigate to the router folder, open up the index.js file in it and edit it with the code block below:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import ViewContact from '@/components/ViewContact'
import NewContact from '@/components/NewContact'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/add',
      name: 'new-contact',
      component: NewContact
    },
    {
      path: '/:person',
      name: 'view-contact',
      component: ViewContact
    }
  ]
})

In the code block above, we imported the components to be used for the different routes that will be used in the app. The Home component is responsible for serving the / route, the NewContact component is used to serve the /add route and the ViewContact component is used to serve the /:person route.

Now that the routes have been defined, we can begin editing the components. Let’s start with the NewContact component. Open up the NewContact.vue file in the components folder. It’s very common for .vue files to be divided into three sections; , and . I’ll highlight the code in each section before putting it all together at the end.

The section contains the main JavaScript code and you can proceed to put in the following code block

  <script>
    import db from './firebaseInit'
    export default {
      name: 'new-contact',
      data () {
        return {
          firstname: null,
          lastname: null,
          emailaddress: null,
          phonenumber: null
        }
      },
      methods: {
        saveContact () {
          db.collection('contacts').add({
            firstname: this.firstname,
            lastname: this.lastname,
            emailaddress: this.emailaddress,
            phonenumber: this.phonenumber,
            slug: this.generateUUID()
          })
            .then(function (docRef) {
              console.log('Document written with ID: ', docRef.id)
            })
            .catch(function (error) {
              console.error('Error adding document: ', error)
            })
        },
        generateUUID () {
          let d = new Date().getTime()
          let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            let r = (d + Math.random() * 16) % 16 | 0
            d = Math.floor(d / 16)
            return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
          })
          return uuid
        }
      }
    }
</script>

In the code block above, the firebaseInit.js file which was created earlier, is imported as db. In the methods object, there’s the saveContact function which essentially saves the new contact to the Firestore DB.
This line db.collection('contacts').add() is a way to add data to the Firestore DB, it’s a way of saying add this data to the collection called contacts (or create one if it doesn’t exist.). Cloud Firestore stores data in Documents, which are stored in Collections.
Inside the .add() function, the contact details gotten from the form which will be created soon is being sent to Firestore along with a unique slug which is generated by the generateUUID function.

Next, we’ll edit the section and edit the HTML needed to create the form to add new contacts.

<template>

  <section class="container">
    <h1>Add New Contact</h1>

    <form @submit.prevent="saveContact">

      <div class="field">
        <label class="label">First Name</label>
        <div class="control">
          <input class="input" type="text" placeholder="First Name" v-model="firstname" required>
        </div>
      </div>

      <div class="field">
        <label class="label">Last Name</label>
        <div class="control">
          <input class="input" type="text" placeholder="Last Name" v-model="lastname" required>
        </div>
      </div>

      <div class="field">
        <label class="label">Email Address</label>
        <div class="control">
          <input class="input" type="email" placeholder="Email Address" v-model="emailaddress" required>
        </div>
      </div>

      <div class="field">
        <label class="label">Phone Number</label>
        <div class="control">
          <input class="input" type="text" placeholder="Phone Number" v-model="phonenumber" required>
        </div>
      </div>

      <div class="field">
        <div class="control">
          <button type="submit" class="button is-link">Submit</button>
        </div>
      </div>

    </form>
  </section>

</template>

In the code block above, we created the HTML form that adds a new contact to the Firestore DB. The value of each input tag is bound to the defined properties in the data() function via Vue.js’ v-model.

The styling for this form was done in the </style section and can be seen below.

<style scoped>

  section {
    height: 100vh;
  }

  h1 {
    font-size: 30px;
    margin: 30px 0;
  }

  .input {
    height: 40px;
  }

</style>

Here’s the NewContact.vue file in its whole entirety.

The next component we’ll go through is the Home component. This component is used to serve the / route and it simply displays all the contacts in the Firestore DB and an optional button to view a contact individually.

Open up the Home.vue file and edit it with the content of the GitHub Gist below.

Let’s go through the code block above, the div with a class of loader-section and conditional rendering v-if=loading is essentially a placeholder and acts as a loading state until the required data is successfully fetched from Firestore.

The div with a class of user-list and directive v-for=person in contacts is the UI needed to populate all the contacts from the data gotten from Firestore. We’ll see how to query data from Firestore next.

In the section of Home.vue, the first line of code is used to import the Firebase config just like we did in the NewContact component. In the created() function, the line db.collection('contacts').get() is used to get all data from the collection named contacts. The data is then pushed into the existing contacts array which was defined in the data() function.

One other thing to note in the code block above is the button/link that leads to the page where you can view an individual contact.

<router-link class="button is-primary" v-bind:to="{ name: 'view-contact', params: { person: person.slug }}">View Person</router-link>

The v-bind:to directive is used to dynamically bind the person segment to the contact’s slug. This basically means that you use the slug to access an individual contact page, so something like this: http://localhost:8080/#/7099198a-5ec5-48ae-b8de-2befb5352f78 where the random string of characters is the slug. This was established in the routes file above where we did something like this:

{
      path: '/:person',
      name: 'view-contact',
      component: ViewContact
    }

The next and last component to be edited is the ViewContact component. Open up the ViewContact.vue file and edit it with the content of the GitHub Gist below:

Let’s go through the code above. The section contains the UI that’s set to display the details of the contact. The various text interpolations in the template section are set to defined properties in the data() function in the section.

The beforeRouteEnter() function is a navigation guard. Navigation guards are used to guard navigations either by redirecting it or canceling it. Navigation Guards may be resolved asynchronously, and the navigation is considered pending before all hooks have been resolved.
That means until the guard has been resolved, users won’t be able to visit the route in which the navigation guard is. It can be used to check if a user is authenticated in an app or some data has finished loading.

The beforeRouteEnter() function accepts three parameters, to, from, next.

  • to: the target Route Object being navigated to.

  • from: the current route being navigated away from.

  • next(): this function must be called to resolve the hook.

In this case, we are using the navigation guard to ensure that the data from Firestore has been successfully retrieved. So how exactly are we getting the data for a particular document in Firestore?

We use the .where() function to query for the data required as seen below:

db.collection('contacts').where('slug', '==', this.$route.params.person).get().then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        console.log(doc.id, ' => ', doc.data())
        this.firstname = doc.data().firstname
        this.lastname = doc.data().lastname
        this.emailaddress = doc.data().emailaddress
        this.phonenumber = doc.data().phonenumber
      })
})

The where() function takes in three parameters; an existing name of a field key in the Firestore DB (in this case, slug), the == sign, and the string in which to query the Firebase DB with (in this case, the $route.params.person string).

One more thing before running the app, we’ll need to add the Bulma CSS framework to the project. You can do that by simply adding the line of code below to the index.html between the head tags.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.1/css/bulma.min.css">

With that being done, you can run the app with the command npm run dev and you should the app live at http://localhost:8080

Differences and similarities between Cloud Firestore and Realtime Database

Now that we have seen how easy it is to get started with Firestore, it’s time to ask questions like:

  • What’s the difference between Cloud Firestore and Realtime Database?
  • How do I determine when to use Cloud Firestore or Realtime Database?
  • Will Realtime Database be deprecated?

There really is no difference between the two technologies, they both offer the same functionalities as seen here, the only advantage Cloud Firestore has, is in terms of scaling. Cloud Firestore was built in close collaboration with the Google Cloud Platform team and that means Cloud Firestore was built to scale right from the beginning.

Also, the Realtime Database is basically a JSON tree where you can store anything with no real structure or organization, Cloud Firestore is actually structured. Cloud Firestore is a document-model database, which means that all of your data is stored in objects called documents that consist of key-value pairs — and these values can contain any number of things, from strings to floats to binary data to JSON-y looking objects the team likes to call maps. These documents, in turn, are grouped into collections.

The Realtime Database may be used in cases where you are trying to optimize for cost and latency, and you can even go ahead to use both databases together. This also means Realtime Database is not going anywhere, both databases co-exist.
It’s also important to note that Cloud Firestore is in beta and it would be good to keep abreast of new developments so as to know if there will be any breaking changes.

Conclusion

In this tutorial, we saw how easy it is to get started with the new Cloud Firestore by Google and also touched on some points when comparing it to the already existing Realtime Database.

The codebase for the app we built above can be seen here. Feel free to play with it and build stuff. The live demo also exists here.

Source:: scotch.io

Custom Overlays with Angular's CDK

overlay preview

You have probably heared of Angular Material haven’t you? If you haven’t, it’s a library that provides you with high-quality Material Design components for Angular. Material Design itself is a visual design language that aims for consistency of user experience across all platforms and device sizes. That’s cool but what if your company has its own opinions about styles and the overall look and feel of the UI? How do we get the best of Angular Material without adopting the Material Design visual language?

Tada 🎉! That’s where Angular Material’s Component Dev Kit (CDK for short) comes into play. The CDK provides us with tools to build awesome and high-quality Angular components without adopting the Material Design visual language. Its goal is to make our life as developers easier and extract common behaviors and patterns shared between multiple Angular Material components. For instance, the datepicker, snackbar, or tooltip have something in common; they need to dynamically open up some floating panel on the screen. But that’s just the tip of the ice berg. There are many different packages for all sorts of things such as a11y that helps us improve the accessibility of our UI components. There’s even a layout package with utilities to build responsive UIs that react to screen-size changes. For a more complete list, please check out the official documentation.

Over at MachineLabs, we thought it would be useful to provide a way to preview generated output files (mostly images), so users don’t have to download it every single time just to take a quick look. So we sat down to build a Google Drive like overlay with the CDK. This post is meant to share our knowledge with the community and to make you comfortable using the CDK for your own purposes.

In this post, we’ll use the CDK to build a Google Drive-like custom overlay that looks and feels much like the one built for MachineLabs. Here’s how it looks like:

The building blocks

Let’s start simple and work our way up to the final, fully-fledged solution which will have a very similar API as the MatDialog service provided by Angular Material. It’s not important to know exactly how the MatDialog works but it’s definitely helpful. If this is new to you, we recommend to check out our post on Easy Dialogs with Angular Material.

Our solution will be a little less flexible but specifically made for showing a file preview inspired by Google Drive. That said, we’d like to have a nice toolbar at the top and the image being rendered in the middle of the screen.

In general, the MatDialog is great for showing content in a dialog box but as soon as we want a little bit of a custom look and feel, something that does not look like a white box with content inside, we would need to roll our own overlay. Luckily, we can use the overlay package from the CDK that has most of the core logic for opening floating panels already baked in. More on that in just a second.

Here are the core building blocks of our application:

application architecture

As we can see, we have two components, one service and a class that represents a remote control to an opened overlay. The AppComponent is the root (or entry point) of our application. This component contains a toolbar and the list of files that we can preview. In addition, it has access to a FilePreviewOverlayService which provides us with the core logic for opnening an overlay. At the same time it’s an abstraction for some “heavy” lifting that should be implemneted in a resuable manner. Don’t be scared, it’s not going to be super heavy and we’ll break it down into comprehensible chunks. Last but not least, there’s a FilePreviewOverlayRef which, as mentioned, is a handle used to control (e.g. close) a particular overlay.

For the overlay we choose to render a component, so we can attach some logic and also add animations to our overlay to engage our users and make them happy. We call this component FilePreviewOverlayComponent.

That’s about it. Now that we have the basic structure in place, we’re ready to look at some code.

Note that this post is the first part out of two in which we lay the foundation for our custom overlay. We’ll build on top of this in the next part and add keyboard support, image preloading and animations.

Setup

Before we can start implementing the custom overlay we need to install the CDK. Simply run npm install @angular/cdk and we’re all set!

Our first overlay

From the MatDialog we know that when we open an overlay we must specify a component type that is then created dynamically at runtime. This means it is not created by using the component tags inside an HTML template. Also, we know that whenever a component is created at runtime, we must add it to our application module’s entryComponents.

Let’s do that and add the FilePreviewOverlayComponent to the arry of entryComponents. In addition, we need to add the OverlayModule to the imports list of the root AppModule:

import { OverlayModule } from '@angular/cdk/overlay';
...

@NgModule({
  imports: [ ... ],
  declarations: [ ..., FilePreviewOverlayComponent ],
  bootstrap: [ AppComponent ],
  providers: [ ... ],
  entryComponents: [
    // Needs to be added here because otherwise we can't
    // dynamically render this component at runtime
    FilePreviewOverlayComponent
  ]
})
export class AppModule { }

From there, creating an overlay is easy. First, we inject the Overlay service. This service has a create() function that we need to call in order to create a PortalHost for our FilePreviewOverlayComponent. Finally we need to create a ComponentPortal from this component and attach it to the PortalHost. Wait, what? Let’s give it a moment and look at some code before taking it apart:

@Injectable()
export class FilePreviewOverlayService {

  // Inject overlay service
  constructor(private overlay: Overlay) { }

  open() {
    // Returns an OverlayRef (which is a PortalHost)
    const overlayRef = overlay.create();

    // Create ComponentPortal that can be attached to a PortalHost
    const filePreviewPortal = new ComponentPortal(FilePreviewOverlayComponent);

    // Attach ComponentPortal to PortalHost
    overlayRef.attach(filePreviewPortal);
  }
}

The first step is to create a PortalHost. We do that by calling create() on the Overlay service. This will return an OverlayRef instance which is basically a remote control for the overlay. One unique attribute of this OverlayRef is that it’s a PortalHost, and once created, we can attach or detach Portals. We can think of a PortalHost as a placeholder for a component or template. So in our scenario, we are creating a ComponentPortal that takes a component type as its fist argument. In order to actually display this component we need to attach the portal to the host.

Ok, but where does the overlay get rendered?

Good question. There’s an OverlayContainer service which creates a container div under the hood that gets appended to the body of the HTML Document. There are a few more wrapper elements created but our component eventually ends up in a div with a class of cdk-overlay-pane. Here’s what the DOM structure looks like:

<div class="cdk-overlay-container">
  <div id="cdk-overlay-0" class="cdk-overlay-pane" dir="ltr">
    <!-- Component goes here -->
  </div>
</div>

Done. That’s all we need to create our very first custom overlay using the CDK. Let’s try it out and see what we got so far:

Our service only exposes one public method open() that will take care of creating a custom overlay. For now, the service is quite simple but it gets more complicated as we implement a more sophisticated and complete (functional-wise) overlay. Therefore it’s a good idea to extract the common logic into a service to stay DRY. Imagine we would have the same logic defined in each component we want to show an overlay. No good, right?

Now that we have layed the foundation for our custom overlay, let’s take it one step further and improve on what we have so far. Let’s add a backdrop and specify a scroll and position strategy. Don’t worry if it’s unclear what scroll and position strategy is all about. We’ll cover that in a second.

Configuring the overlay

When creating an overlay, we can pass an optional configuration object to create() to set the desired options, e.g. whether it has backdrop, the position or scroll strategy, width, height and many more. Here’s an example:

// Example configuration
overlay.create({
  width: '400px',
  height: '600px'
});

First of all, we allow the consumer of our API to override certain options. Therefore, we update the signature for open() to also take a configuration object. In addition, we define an interface that describes the shape of the configuration from a consumer perspective:

// Each property can be overridden by the consumer
interface FilePreviewDialogConfig {
  panelClass?: string;
  hasBackdrop?: boolean;
  backdropClass?: string;
}

@Injectable()
export class FilePreviewOverlayService {
  open(config: FilePreviewDialogConfig = {}) {
    ...
  }
}

Next, we define some initial values for the config, so that, by default, every overlay has a backdrop alongside a backdropClass and panelClass:

const DEFAULT_CONFIG: FilePreviewDialogConfig = {
  hasBackdrop: true,
  backdropClass: 'dark-backdrop',
  panelClass: 'tm-file-preview-dialog-panel'
}

@Injectable()
export class FilePreviewOverlayService {
  ...
}

With that in place, we can define a new method getOverlayConfig() which takes care of creating a new OverlayConfig for the custom overlay. Remember, it’s better to break down the logic into smaller parts instead of implementing everything in one giant function. This ensures better maintainability but also readability of our code.

@Injectable()
export class FilePreviewOverlayService {

  ...

  private getOverlayConfig(config: FilePreviewDialogConfig): OverlayConfig {
    const positionStrategy = this.overlay.position()
      .global()
      .centerHorizontally()
      .centerVertically();

    const overlayConfig = new OverlayConfig({
      hasBackdrop: config.hasBackdrop,
      backdropClass: config.backdropClass,
      panelClass: config.panelClass,
      scrollStrategy: this.overlay.scrollStrategies.block(),
      positionStrategy
    });

    return overlayConfig;
  }
}

Our method is quite simple. It takes a FilePreviewDialogConfig and creates a new OverlayConfig with the values from the given configuration. However, there are two important things to mention. One is the scrollStrategy and the other one is the positionStrategy.

Scroll strategy

The scroll strategy is a way of defining how our overlay should behave if the user scrolls while the overlay is open. There are several strategies available as part of the CDK, such as

  • NoopScrollStrategy: does nothing
  • CloseScrollStrategy: automatically closes the overlay when scrolling
  • BlockScrollStrategy: blocks page scrolling
  • RepositionScrollStrategy: will reposition the overlay element on scroll

For our file preview overlay, we are going to use the BlockScrollStrategy because we don’t want the user to be scrolling in the background while the overlay is open.

The scrollStrategy takes a function that returns a scroll strategy. All strategies are provided by the Overlay service and can be accessed via the scrollStrategies property:

const overlayConfig = new OverlayConfig({
  ...
  // Other strategies are .noop(), .reposition(), or .close()
  scrollStrategy: this.overlay.scrollStrategies.block()
});

If we don’t specify a strategy explicitly, all overlays will use the NoopScrollStrategy.

Position strategy

The position strategy allows us to configure how our overlay is positioned on the screen. There are two position strategies available as part of the CDK:

  • GlobalPositionStrategy: used for overlays that need to be positioned unrelated to other elements on the screen. This strategy is mostly used for modals or root-level notifications.
  • ConnectedPositionStrategy: used for overlays that are positioned relative to other elements. This is commonly used for menus or tooltips.

We’ll be using the GlobalPositionStrategy for our overlay because it’s supposed to be positioned globally on screen, unrelated to other elements.

Similar to the scrollStrategy we can access all position strategies through the Overlay service like so:

const positionStrategy = this.overlay.position()
  .global()
  .centerHorizontally()
  .centerVertically();

const overlayConfig = new OverlayConfig({
  ...
  positionStrategy
});

With the configuration in place, we go ahead and define another method createOverlay() that hides the complexity of creating an overlay with a given configuration:

@Injectable()
export class FilePreviewOverlayService {
  ...
  private createOverlay(config: FilePreviewDialogConfig) {
    // Returns an OverlayConfig
    const overlayConfig = this.getOverlayConfig(config);

    // Returns an OverlayRef
    return this.overlay.create(overlayConfig);
  }
}

We now refactor our open() method to generate a default config and utilize createOverlay():

export class FilePreviewOverlayService {
  ...
  open(config: FilePreviewDialogConfig = {}) {
    // Override default configuration
    const dialogConfig = { ...DEFAULT_CONFIG, ...config };

    const overlayRef = this.createOverlay(dialogConfig);
    ...
  }
}

Here’s what it looks like in action:

Our overlay looks much more like an overlay as we have imagined it in the beginning. The good thing is that most of the heavy lifting is taken care of by the CDK, such as dynamically creating a component, block page scrolling, or positioning.

So far, so good, but we are still missing some very fundamental functionality. We can open an overlay but what about closing it? This it not yet possible, so let’s go ahead and add this feature.

Closing overlays with a remote control

Just like we use remote controls to snap between television channels, we want a remote control to close our overlays. It will provide an API for modifying, closing, and listening to events on the overlay instance. Especially if we want to be able to close the dialog from within the overlay component, and optionally return a value to the consumer.

Our remote control will be a simple class that exposes only one public method – close(). For now we keep simple and extend it as we introduce more features. Here’s what it looks like:

import { OverlayRef } from '@angular/cdk/overlay';

export class FilePreviewOverlayRef {

  constructor(private overlayRef: OverlayRef) { }

  close(): void {
    this.overlayRef.dispose();
  }
}

When implementing the remote control, the only thing we have to make sure is that we need access to the OverlayRef. It’s a reference to the overlay (portal host) that allows us to detach the portal. Note that, there’s no @Injectable decorator attached to the class which means that we can’t leverage the DI system for this service. This, however, is no big deal because we will manually create an instance for every overlay and therefore we don’t need to register a provider either. Theoretically, we could open multiple overlays stacked on top of each other where each overlay has its own remote control. The DI system creates singletons by default. That’s not what we want in this case.

What’s left to do is to update our open() method to create a remote control and return it to the consumer of our API:

@Injectable()
export class FilePreviewOverlayService {
  ...
  open(config: FilePreviewDialogConfig = {}) {
    ...
    const overlayRef = this.createOverlay(dialogConfig);

    // Instantiate remote control
    const dialogRef = new FilePreviewOverlayRef(overlayRef);
    ...
    // Return remote control
    return dialogRef;
  }

Notice how we pass in the overlayRef when creating a new FilePreviewOverlayRef? That’s how we get a hold of the PortalHost inside the remote. Instead of implementing a class that represents a reference to the open overlay, we could have returned the OverlayRef directly. However, it’s not a good idea to expose lower-level APIs because users could mess with the overlay and detach the backdrop for instance. Also, we need a little bit more logic later on when we introduce animations. A remote control is a good way of limiting the access to the underlying APIs and expose only those that we want to be publicly available.

From a consumer perspective we now get a handle to the overlay that allows us to programatically close it at some point. Let’s go ahead and update AppComponent accordingly:

@Component({...})
export class AppComponent  {
  ...
  showPreview() {
    // Returns a handle to the open overlay
    let dialogRef: FilePreviewOverlayRef = this.previewDialog.open();

    // Close overlay after 2 seconds
    setTimeout(() => {
      dialogRef.close();
    }, 2000);
  }
}

Here’s our code in action. Remember, once we open an overlay it will automatically close after 2 seconds:

Awesome! We are making serious progress and it’s not far until we reach the top of the mountain.

Improving ergonomics

In the previous sections we have mainly improved the overlay under the hood and layed a foundation for upcoming features. In this section we want to focus on improving the overlay’s ergonomics. This means that we want to be able to close the dialog when we click on the backdrop.

Turns out that the backdrop logic is extremely easy with the CDK. All we have to do is to subscribe to a stream that emits a value when the backdrop was clicked:

@Injectable()
export class FilePreviewOverlayService {
  open(config: FilePreviewDialogConfig = {}) {
    ...
    // Subscribe to a stream that emits when the backdrop was clicked
    overlayRef.backdropClick().subscribe(_ => dialogRef.close());

    return dialogRef;
  }
}

That’s it! Imagine how much work this would be without the CDK.

From here we could take it one step further and also close the overlay when a user naviagtes back in the browser history. For our application, however, this doesn’t make much sense because we are not using the router and there’s only one page that we render out to the screen. But feel free to give it a shot! Hint: use the Location service and subscribe to the browser’s popState events.

Sharing data with the overlay component

The goal of this post was to implement a generic file preview dialog rather than a static one. At the moment the overlay is quite static and there’s no way we can share data with the overlay component. Sharing data means we want to be able to provide an image that will be available within the component. After all it’s supposed to be a file preview. Therefore, we need to think about how we can share data with the component that is dynamically created.

Luckily, Angular has a hierarchical dependency injection system (DI for short) that we can leverage for our purpose. For more information on Angular’s DI system, check out this post.

In a nutshell, the DI system is flexible enough that we can reconfigure the injectors at any level of the component tree. That said, there is no such thing as the injector. An application may have multiple injectors and each component instance has its own injector. You hear the bells ring? Right, we can create our own custom injector and provide it with a list of custom injection tokens. It sounds more complicated than it actually is.

Turns out, the CDK already has a class PortalInjector that that we can use to provide custom injection tokens to components inside a portal. This is exactly what we need. Let’s break ground and implement a function createInjector() that creates a new PortalInjector and defines a list of custom injection tokens.

@Injectable()
export class FilePreviewOverlayService {
  ...
  private createInjector(config: FilePreviewDialogConfig, dialogRef: FilePreviewOverlayRef): PortalInjector {
    // Instantiate new WeakMap for our custom injection tokens
    const injectionTokens = new WeakMap();

    // Set custom injection tokens
    injectionTokens.set(FilePreviewOverlayRef, dialogRef);
    injectionTokens.set(FILE_PREVIEW_DIALOG_DATA, config.data);

    // Instantiate new PortalInjector
    return new PortalInjector(this.injector, injectionTokens);
  }

In the code above we create a new WeakMap, set our custom injection tokens that we want to be available (injectable) in the overlay component, and finally instantiate a new PortalInjector. The important part though is that we also specify a parent injector (first argument) which is mandatory. Also notice the second argument where we pass in our injection tokens.

There are two things that we are providing. The first token is the FilePreviewDialogRef. Having the remote control at hand, allows the overlay component to close itself. This is very useful because there will definitely be a close button somewhere. The second token is a custom InjectionToken that stores the data that we want to share with the component.

For the InjectionToken we create new file file-preview-overlay.tokens and instantiate a new InjectionToken:

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

import { Image } from './file-preview-overlay.service';

export const FILE_PREVIEW_DIALOG_DATA = new InjectionToken<Image>('FILE_PREVIEW_DIALOG_DATA');

Next, let’s update our FilePreviewDialogConfig so that the user can specify an image that will be used by the overlay component:

interface Image {
  name: string;
  url: string;
}

interface FilePreviewDialogConfig {
  panelClass?: string;
  hasBackdrop?: boolean;
  backdropClass?: string;
  data?: Image;
}

@Injectable()
export class FilePreviewOverlayService {
  ...
}

For better readability we’ll also refactor our open() method and create a new attachDialogContainer() function that now takes care of creating the injector and component portal, as well as attaching the portal to the host.

@Injectable()
export class FilePreviewOverlayService {
  ...
  private attachDialogContainer(overlayRef: OverlayRef, config: FilePreviewDialogConfig, dialogRef: FilePreviewOverlayRef) {
    const injector = this.createInjector(config, dialogRef);

    const containerPortal = new ComponentPortal(FilePreviewOverlayComponent, null, injector);
    const containerRef: ComponentRef<FilePreviewOverlayComponent> = overlayRef.attach(containerPortal);

    return containerRef.instance;
  }
}

With that in place, we can now update our FilePreviewOverlayComponent and inject the tokens that we have defined on a component level with the help of a custom injector.

export class FilePreviewOverlayComponent {
  constructor(
    public dialogRef: FilePreviewOverlayRef,
    @Inject(FILE_PREVIEW_DIALOG_DATA) public image: any
  ) { }
}

Finally with a little bit of styling we come much closer to what we were trying to achieve. We can now define data that will be passed to the overlay component and render an image onto the screen:

Where to go from here

This is it. Although creating custom overlays is something that’s more or less tricky to do, this task becomes rather easy with UI libraries like Angular Material that provide us with a common set of tools to build awesome and high-quality Angular components. More specifically, by extracting common behaviors and patterns into a so called Component Dev Kit, it becomes extremely easy to build a custom overlay.

Where to go from here? As mentioned in the beginning, this was only part one and we haven’t fully re-built the Google Drive-like file preview yet. In the next post we will build on top of this and implement keyboard support, image preloading and add animations in order to make our overlay more engaging.

Source:: Thoughtram

Node.js Weekly Update - November 17

By Tamas Kadlecsik

Node.js Weekly Update - November 17

Below you can find RisingStack‘s collection of the most important Node.js updates, projects & tutorials from this week:

Node v9.2.0 (Current) released on 14 November.

Notable changes:

  • crypto:
    • Support building with both 1.1.0 and 1.0.2 (David Benjamin)
  • fs:
    • fs.realpathSync.native and fs.realpath.native are now exposed (Ben Noordhuis)
  • process:
    • expose process.ppid (cjihrig)

Debugging Memory Leaks and Memory Bloat in Node.js

Memory issues can be daunting when you first encounter them.

The aim of this article is to show how to deal with a memory leak. Although it can be seemingly difficult to deal with it, they should be no more of a problem than an average bug.

Node.js security: Are developers confident in the quality of their code?

Nodesource and Sqreen created a survey where they asked nearly 300 CTOs, CIOs about their Node.js code security. This survey revealed some interesting data of security issues, that you can all read in this post.

…while the developer community fully understands the risks of operating in the open Internet and the complexities of building secure code, developers are not taking advantage of tools that can identify and mitigate threats.

Introducing Fn: “Serverless must be open, community-driven, and cloud-neutral”

Fn, a new serverless open source project was announced at this year’s JavaOne. There’s no risk of cloud lock-in and you can write functions in your favorite programming language.

In this interview, Bob Quillin, VP for the Oracle Container Group talks about Fn, its best features, next milestones and more.

Survey: Learning Node.js in 2018

We would like to continue supporting the Node.js community with free learning materials in 2018 as well, so we’re searching for the topics that are hard to understand or get right. We’d be thrilled if you could help us recognize the areas to cover, by completing this

Secure Your Node.js Website With OpenID Connect

In this post, you’ll see how to build a simple web application using Node.js and Express.js, and learn to secure it with authentication.

Native Pattern Matching for Javascript

The pattern matching is basically a switch on steroids, you can create powerful conditions such based on Object properties or Array content without manipulating the Object or Array itself. That amount of power leads you write functional, immutable, and expressive code instead imperative, which reduces a lot of complexity and bugs.

Wiring up a GraphQL server with Node and Express

Graph Query Language is one of those things that you see mentioned in blog posts and articles but you are unsure exactly what it is.

Find out more about this language in this post; what is it, how to set it up, and how to build a server with Node and Express.

05 Dashcam and GPS with NodeJS- Building a Raspberry Pi Carputer

Ever wondered how to build a Raspberry Pi-powered carputer? Find it out from this tutorial series by Austin Ellsworth. You can find his resources on Github as well.

Node.js Weekly Update - November 17

Previously in the Node.js Weekly Update

In the previous Node.js Weekly Update we collected the latest news on Node.js such as the Node v9.1.0 and Node v8.9.1 (LTS) updates, catching without awaiting, querystring, HTTP/2 in the Node Core, creating a Twitter bot, a great article on core values, and much more! Click if you missed it!

We help you to stay up-to-date with Node.js on a daily basis too. Check out our Node.js news page and its Twitter feed!

Source:: risingstack.com

A Look at Angular Alongside Vue - Learning Materials

By John Papa

I spent a few days on and off learning parts of Vue to write a small app. I wrote the same app with Angular. I’m sharing my experience of working through Vue for the first time to help others that may be curious about the JavaScript framework landscape.

This time I want to share where I went for learning materials and how they worked out for me.

Here are the posts in this series, if you want to catch up or jump around:

Learning Materials

OK, I admit … at first, I didn’t use any learning materials. I googled Vue CLI, found the official Vue CLI, installed it, and ran it.

Vue CLI

This has to do with how I learn. I like to explore first. This helps me figure out what types of things makes sense instantly. it also helps me start formulating questions. So the first place I learned is the Vue CLI’s github page.

The README.md said to run vue init , so I did. After all, who am I to argue? I think it’s cool that there are different templates we can use to generate a Vue app. Although this was my first source of confusion … I had to choose which template to start with. This meant I had to have some idea of what each template does and what that means for a Vue project. Fortunately, this wasn’t difficult.

There is this link in the README.md that explains the recommended templates. I started with the simple template. This seemed a good place to start so I could get a sense of how a Vue app works without any additional ceremony. So I tried it.

The Simple Template

I ran vue init simple vuesimple and I got exactly 1 file. That’s right, ONE FILE. Take a look for yourself:

The index.html points to Vue in a CDN. The code was quite simple too … check out the Vue code in the tags:

This is our first look at Vue code! OK, let’s see what we got here. There is a Vue object instance and it seems to references an HTML element by the id #app. Alright. Then it declares some data properties. These appear to be a model that I can bind to the Vue view (Don’t sigh, you knew I was going there). Then it declares a method which formats a URL. The code for this component (I’m assuming component is the right word at this point) seems pretty simple.

Next, I looked in the HTML template to see how those data properties (my model) is bound to the app. This is pretty familiar to me as there are squiggly braces all over the place. They help bind the model properties to the template. For example, we see {{ greeting }} which renders the “Welcome to your Vue.js app!” to the template. It also binds the method in the template with the squigglies. We call this interpolation, or handlebars, or mustaches … or I call them lovingly “squigglies” 🙂

Looking further, I also see some :href references in the template. This appears to be binding the href property of the element to the value. For example, binds the docsURL model value to the anchor tag’s href. Again, quite simple.

And of course, running the app is simple as launching the index.html in the browser. So far so good! But I’m pretty sure I don’t know a lot at this point.

WebPack Simple

Next I generated a simple webpack project for Vue with vue init webpack-simple vuewebpacksimple. I went from one file in the simple template to about 10 files in the webpack-simple template. Still, not bad. Just a few more things to look through. And I knew webpack and a build process was coming … a build process is just par for the course in modern JavaScript.

The main.js file caught my eye. This kicks off the app creating the Vue object instance and referencing the HTML element.

import Vue from 'vue'  
import App from './App.vue'

new Vue({  
  el: '#app',
  render: h => h(App)
})

This moves the bootstrapping code to its own file, which is a good thing in my opinion. At least it was comfortable for me. I then opened the App.vue file, which is where most of the interesting work is being done.

The template contains a single binding for the msg and a lot of HTML. The msg is a model in the same file. This is just a trimmed down model, similar to what we had in the previous example. This time we just have a single model property and no methods. Of course, we can add whatever we like.

It get’s interesting here as the next thing we see is styles for the component. The App.vue file may contain its own styles (or SASS if you prefer). I later learned that these can be scoped or we can allow them to cascade to other components. Again, a pretty familiar concept on the Web these days.

VS Code and File Names

I noticed that the files are not .js nor are they .ts files. Instead, we have a framework specific file extension of .vue. No big deal, except that to get my VS Code editor to recognize Vue. I went searching for Vue extensions and found two that caught my eye. First, I found that Sarah Drasner, who works with me and is a core contributor to Vue, created a Vue snippets extension. I like me some snippets, so I grabbed that up. I also saw the Vetur extension, which was recommended by VS Code. I went to install both … then realized that Sarah did us a solid by making her extension depend on the Vetur extension. So I got 2 birds with one install.

Once I installed these, my Vue code lit up inside VS Code. OK, well, no lights … but VS Code recognized Vue and made my life much easier 🙂

I highly recommend you grab these extensions. Unless you like pain … and in that case, maybe you should just use notepad. (Yes, I kid)

You can get them both from this one extension.

Running the App

Next I wanted to run the app. I ran vue from the command line and didn’t see anything in the help that said how to run it. There was a build command, but I want to run it and see it. I could have run vue build and then browse to the index.html. My preference is to see if there is a dev server so I can write code, see the app, edit the code, see it in the app. Rinse and repeat … you know, what devs do all day.

So I opened package.json and saw the script for npm run dev. I ran that and got slammed with an error about missing node modules. Oops! The Vue CLI did not install those for me, so I ran npm install and then re-ran npm run dev.

The Vue app built. The browser was launched. And there was my app! Next, I changed the msg model and the new text appeared in the browser.

What About Learning Materials

OK, so I didn’t go read any docs or watch videos. But the few minutes I spent so far were quite productive. I could create an app, a model, a template, and bind some values and run it. Not bad for not reading any docs or watching videos.

Of course, there is a whole lot more to cover. My next move was to figure out how to create multiple components, communicate between them, handle events, call an external client service, and communicate over HTTP. This is when I hit up the official Vue docs and started poking around. They are pretty straight-forward. Give them a look.

But this is a good place to stop. The experience so far was pretty smooth and only took a few minutes. Come back and visit in a few days when I post more about my first journey into Vue.

Source Code

You can find the source code for these apps here:

Source:: johnpapa

Vue.Js and React.Js – a Quick Comparison

By Nataliia Kharchenko

React.js vs Vue.js

Frontend developers utilize a variety of tools. Discussion of these tools and arguing which one is the best will easily grow in a holy war, as every developer has his own preferences in terms of methods of working and using programming languages. That is why the wisest decision one can make is to test different JS frameworks by his own and choose what is best for fulfilling his personal tasks. This is what programmers do when they want to assess something.

As of today, there are two popular frameworks (along with Node.js frameworks) that are highly valued by most developers – React.js and Vue.js. But which one is better? It depends on what tasks you are going to resolve. Let’s review strong and weak sides of every tool – it may help you to make the right choice: Vue or React.

Vue.Js & React.Js – General Description and Similarities

Before you proceed to comparison of Vue.Js vs React, make sure that you clearly understand what these tools are used for and what their possibilities include. Both of them relate to the category of JavaScript libraries or frameworks, and both of them are utilized in interface design. Apart from their common purpose, the two frameworks have some other things in common:

  • Both Vue.Js and React.Js are based on the Virtual DOM model.
  • Component-based structure and reactivity are distinctive features of both tools.
  • They are intended for working with the root library, while all the additional tasks are transferred to other libraries.

At the same time, there are certain differences between the two tools. For example, many developers mention its ample supporting infrastructure and many visualization tools among the benefits of using React.Js. Also, web app developers say that React Native is more simple-to-use for apps creating.

If we take a basic phrase “Hello, world”, which is used by all programmers worldwide for testing programming languages, we’ll see that the code is a little shorter and simple with Vue.

Hello World from Vue:

<!DOCTYPE html>
<html>
<head>
    <title>Vue Hello World</title>
    <script src="https://vuejs.org/js/vue.min.js"></script>
</head>
<body>
    <div id="app">
        {{ message }}
    </div>
     <script>
         new Vue({
              el: '#app',
              data: {
                  message: 'Hello from Vue'
                }
         });
         </script>
</body>
</html>

Hello World from React:

<!DOCTYPE html>
<html>
    <head>
        <title>React Hello World</title>
        <script src="https://fb.me/react-15.0.0.js"></script>
        <script src="https://fb.me/react-dom-15.0.0.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
   </head>
   <body>
       <div id="greeting"></div>
       <script type="text/babel">
           var Greeting = React.createClass({
               render: function() {
                   return (
                      <p>Hello from React</p>
                   )
               }
           });
           ReactDOM.render(
                <Greeting/>,
                 document.getElementById('greeting')
           );
       </script>
   </body>
</html>

But does it mean that this framework is better? Well, not in every instance. Let’s review advantages and disadvantages of both tools in detail.

Strengths and Weaknesses of Vue.Js and React.Js

A lot of interface designers and apps developers unanimously say that would prefer utilizing Vue.Js in the following situations:

You create web apps with templates.

In Vue, a compulsory action is adding attributes to HTML layout. It is like data binding in Angular. One of Vue.Js advantages is a faster and simpler process of creating apps thanks to Vue.js template. An example of such apps is an app where one can alter the name of the button displayed by one click.

As for React, it doesn’t use templates, so to execute this task one needs to launch DOM in JS. It will take more time and efforts. If you are going to work with templates, you need to know advanced HTML. But some plain functions can be written with standard HTML and JS.

You need something simple and efficient

You can upload a Vue-written app right from your browser without the need for transpilation. Thanks to this, the Vue library may be added without problems to the whole project.

Vue’s design is simpler in general. For example, value processing in Vue differs from value processing in React. Thus, React analyzes both previous and current actions and then adds the relevant data to DOM based on the result of the analyses. For this reason you can’t alter any values directly.

In Vue framework you can change values easily. It automatically makes relevant changes in DOM every time when the values are changed. This solution is rather efficient, but it has at least one drawback if compared with React. Vue can’t track data editing and deletion, which sometimes can be a problem.

You need a small but quick app

The mechanism of working of both frameworks is similar: a virtual DOM is created and synced to the real DOM. When the valued in a virtual DOM are changed, these changes are automatically transferred to a real DOM.

This process can be optimized in both systems. But in Vue it works faster, while the size of the library itself is lesser – just 25.6 kb. The total size of React is twice as large – 37.4 kb of DOM plus 11.4 kb of the library. However, among React.JS advantages is a wider array of API options.

Being a larger, heavier and more complicated framework, React.JS is recommended for use in the following situations:

You want to develop a large app

As we’d found out previously, many developers prefer Vue for creating small apps. But React is definitely better for larger apps developing. Why React.JS? It tends to be more flexible and adjustable. As we know, Vue uses templates, which makes the development process simpler and faster. But when an app is big, these benefits tend to turn into drawbacks. Often use of templates makes restructuring of an app impossible or too complicated. React’s code with JS templates is reusable, and when you create React app, you can easily restructure it in future.

You want to develop both web and mobile apps

React offers React Native library, which can be used for developing mobile apps in JS. It looks very similar to React.JS, so if you know how to use React, you’ll quickly understand how to use it. React Native lets create a working mobile app without any professional knowledge and skills.

You want a great technical support and an array of ready-made solution

Though both Vue and React are popular frameworks, popularity of the latter is immeasurably greater – 2.5 mln of downloads vs Vue’s 225 thousand per month. What does it mean in practice? The framework is widely discussed on dedicated forums and in social media. You’ll find a variety of ready-made instructions and solutions, manuals and guides. Finally, React was created by a team of professional developers from Facebook, which means that you’ll get a great level of support if you have any questions.

A Bottom Line

Vue.JS and React.JS are two popular developers’ tools that have much in common. They are relatively light-weight, fast and flexible. Both of them use virtual DOMs and quickly synchronize it with the real DOM. However, there are some subtle differences between the frameworks.

Vue has the following advantages over React:

  • it is smaller and faster;
  • convenient templates simplify the process of developing;
  • it is simpler in terms of syntax.

React has the following advantages over Vue:

  • gives more flexibility in large apps developing;
  • easier to test;
  • suitable for mobile apps creating;
  • more information and solutions available.

But anyway, the best way to choose the best tool for resolving particular issues is to test different options. So, try them both to make a choice.

Source:: scotch.io

A Look at Angular Alongside Vue - File Structure

By John Papa

Vue app

I JavaScript. I love how it is constantly evolving. The buzz around Vue and how it is similar to Angular has intrigued me, so recently I explored Vue. I wanted to get a sense of how it compared, how it works, and how it feels to develop an app with it. I spent a few days on and off learning parts of Vue to write a small app.

tldr; … I enjoyed my first experience with Vue. I enjoy Angular. Seeing multiple ways to tackle apps is a good experience.

Other posts will follow on the learning materials, things I stumbled on, things I learned that may help others, things I learned that I’ll now use.

You can find the source code for these apps here:

Along the way, I took notes so I could share my experience. A few things to keep in mind as I share these thoughts over a few posts:

  1. I’m not leaving Angular. I love JavaScript, and I find it rewarding and valuable to understand the landscape.

  2. I am not a Vue expert, nor do I play one on TV. I used the Vue docs and a little googling when I got stuck. I asked Sarah Drasner to help me with a few specific parts of my code that worked but I was unhappy with. I will explain where she really helped clarify and improve the app for me. Everyone say “Thank you, Sarah!”

  3. Most importantly … My intention is to show a simple comparison and share my first experience with Vue. This is not a complete comparison. No conclusions about who wins or loses should be made. The right question is how we can all learn from each other and the tools at our fingertips.

There are a lot of similarities between Vue and Angular that really helped me pick up Vue. In fact, if you look closely you can feel some influence from AngularJS (v1.x) and React, as well. This is a good thing … the Web is learning from its landscape. We all benefit from this.

App Baseline

I intentionally designed the apps to follow a similar pattern. The app should show a list of heroes. The list should be retrieved over HTTP. The app must allow retrieving, adding, deleting, and updating of the heroes. The app must also allow some basic styling, a selection from the list of heroes, and save/cancel on the saving of changes. This is a pretty standard formula for most apps.

I used VS Code for building both apps, because … well .. it’s freaking awesome! For best results, grab the Angular Essentials extension and the Vue Snippets extension. They both make VS Code light up even more with Angular and Vue.

Each app has:

  1. a component to contain the app
  2. a component for the hero list
  3. a component for editing heroes
  4. a service to handle the HTTP calls

Both the Angular and Vue apps also contain files for the index.html and a main.js. Both of these files help kick off their respective apps.

Angular app

Both apps also have build systemns, were generated using their respective CLI tools, and use the same node.js server with a Cosmos DB database (using a MongoDB model). I also configured both to work with docker.

File Differences

There are some differences in the files in the apps.

  1. The Angular app is written with TypeScript and the Vue app in Babel. I chose to use the default and predominant languages for each.

  2. The Angular app has a hero.ts file, which contains a Hero model. It wasn’t necessary, but it very common since we can take advantage of types in TypeScript.

  3. Both apps use SASS. The Vue app’s SASS is inline inside the *.vue files. The Angular app’s SASS is in separate files. The Angular CLI supports inline styles with CSS, but it won’t compile SCSS natively inline.

  4. The Angular app contains an extra file for the NgModule. This is the app.module.ts. It serves as a manifest for the main features of the Angular app.

  5. Naming conventions are slightly different.

Both allow for inline styles or separate files. Both allow for inline templates or separate files. Both allow for scoped styles. I tried to keep the apps relatively similar for this comparison, but obviously, you could deviate from this if you prefer.

What Does it Mean?

Not much. And that’s a good thing. They are quite similar in file structure and naming.

The number of files and the file names for these apps are not that important in the grand scheme. They are quite close and relatively easy to map from Angular to Vue to Angular. The takeaway here is that conventions are a good thing, and Vue and Angular both follow some.

Hey – if you know me, you know I like to follow conventions in style guides 🙂

Source:: johnpapa

Use Dynamic Components to render HTML for 3rd party libraries

By Juri Strumpflohner

Dynamic components in Angular are very powerful and help you solve the trickiest problems. In this example we’re going to learn how we can leverage dynamic Angular components to render the HTML of a popup controlled by a Leaflet map. We’ll go step by step and also learn about the things you need to watch for when instantiating components dynamically.

Source:: juristr.com