Call CDN delivered library in Angular Component - javascript

I am trying to interact with the HelpScout beacon via their API methods however struggling to interact with the DOM from the controller.
I have tried running functions such as
document.HS.beacon.ready(function() {
// Open the Beacon as soon as it's ready
this.open();
});
on various lifeCycle hooks such as ngAfterViewInit() however, I get a number of errors in the compiler for as HS is not a property on document.
There are numerous component based JS frameworks that must have a robust solution for interacting with libraries that are delivered via CDN? I would rather they packaged up the code and ran it as an npm / yarn package, however that is not the case.
Many thanks in advance.
EDIT: I note that they are simply injecting this code : https://djtflbt20bdde.cloudfront.net. I might just run this locally? Ideas?

I suppose you could init the Beacon object via script tag, that creates an instance of the Beacon object as a property of window. If you need to interact with this object inside an Angular component or service, you should declare it first (in my case, I needed to destroy the Object):
import { Component } from '#angular/core';
declare let Beacon: any ;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
closeBeacon(){
Beacon('destroy');
}
}

Related

Can I use an angular service without mentioning it in NgModule's providers?

I'm new to Angular and following freecodecamp tutorials on youtube. They're 2 years old.
In services tutorial, it is mentioned that we need to mention the Service in providers list in root NgModule to make it work. But I haven't mentioned it in providers.
What I observed is that in the tutorial, there is no providedIn in the Injectable(). But when I created a new service in Angular 10, I got it by default in the Injectable(). The service is working without any issues so far.
Are these 2 same?
Can we mention the providedIn: 'root' and leave it without mentioning in providers list to make it work and viceversa?
You can make an Angular service singleton to share the same instance in the whole app by doing one of the two possibilities:
add it to providers array in your root module (app module)
make the service provided in root
#Injectable({
providedIn: 'root'
})
but the best is to use #Injectable() decorator of the service itself to make it Tree-shakable.
if now you can provide the service in your lazy loaded modules level so the service will have a new instance for each module
or provide the service in the component lever thus your component and its children will have the same instance
#Component({
selector: 'parent',
template: `...`,
providers: [ YourService ]
})

Is it possible to bootstrap ng2+ app manually from javascript?

Is it possible to bootstrap NG2+ app manually from jquery / javascript code?
I need something like we do in TypeScript:
platformBrowserDynamic().bootstrapModule(AppModule);
The situation is being approached from wrong end.
In order to do that, platformBrowserDynamic and AppModule should be exposed to global scope, and they aren't. While it is possible to load Angular as UMD modules and have it as ng global, this would result in 2 copies of Angular, and AppModule would still be unreachable.
It's possible by exposing a function to global scope:
window.bootstrapApp = () => platformBrowserDynamic().bootstrapModule(AppModule);
But considering that the objective is to quickly check user permissions with non-Angular code, the right place to do this is still main.ts. And the preferable way to postpone application initialization is to do checks on bootstrap with APP_INITIALIZER provider.

Angular 2 and component tree

I'm studying Angular 2 internal components and behaviors and I'm having some questions concerning the component tree management.
In a web app based on components, it's clear that we have a component tree. One component is composed of another one, from top to bottom, and it's really powerful.
But now, I m wondering how does angular 2 manages the representation of this component tree internally ?
What I mean there is that we never say in an angular component, what components will be inside of it, except in the template.
For example, I never say in my HomeComponent definition that it owns a PrestaCardComponent :
import { Component, OnInit, Inject } from '#angular/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
prestations: Array<any>;
featurettes: Array<any>;
constructor( #Inject('AppStore') private appStore: any) {
this.prestations = [];
this.featurettes = [];
}
ngOnInit() {
}
}
Except in my template :
<div *ngFor="let prestation of prestations" class="col-md-4 m-b">
<app-presta-card [title]="prestation.title" [content]="prestation.content" [image]="prestation.image"></app-presta-card>
</div>
What I understand it means
It means that Angular 2 is able to create the virtual component tree, by reading the different templates.
How can it be possible ? How does it work ?
Use Augury. you will get a clear insight.
NgModules are key to understanding how Angular deciphers the template when it parses it.
Look into the definition of these properties while decorating with #NgModule,
declarations : List of components, directives, and pipes that belong to this module.
imports : List of modules to import into this module. Everything from the imported modules is available to declarations of this module.
exports : List of components, directives, and pipes visible to modules that import this module.
using this knowledge Angular knows what selector means what, and using Reflection it gets Metadata for the component.
Of course there is more to it, but this may be a start.
Hope this helps!!
All the configuration of your components are rooted in an NgModule.
As Madhu Ranjan already mentioned in his answer there are the following 3 important parts in an NgModule, namely being:
declarations : List of components, directives, and pipes that belong to this module.
imports : List of modules to import into this module. Everything from the imported modules is available to declarations of this module.
exports : List of components, directives, and pipes visible to modules that import this module.
Actually there is even an FAQ for NgModule as it was a major change in the angular2 architecture since (I think) RC5.
Each and every component has to be part of an NgModule. It declares a part of your application which functionalities belong to each other. You can even nest NgModules inside each other with the imports part of it.
A positive part IMO is that you can organize your application very well with this structure as each angular module has its own routing configuration.
Furthermore you can limit accessability of services that should be used by declaring them inside e.g. a (sub-) module of another module just to name a few important features.
Check out the Angular2 Docs for more information about this and many more subjects. It is pretty detailed and IMO very easy to understand as the angular team took alot of effort of keeping it up to date and clean (when you don't mind searching a bit for the parts you need as the topic grouping is kinda crappy in the docs).

Add an external Javascript file depends of Component Name in Angular2

Currently I'm creating an app using Angular2 and Typescript.
I have different components for different sections in the application (Home, Profile page, ...) and a JS file for each section (home.js, profile.js).
I'm wondering if it's possible to include this file depends of the component is being loaded.
Other thing I have tried is to add the javascript file into the view of the component but looks like Angular is stripping it out.
Any advice or a better way to do this would be really appreciated.
Thank you
Finally I got it solved by myself.
What I've done is to implement AfterViewInit interface on my components, and load the script using jQuery.getScript method.
import {Component, AfterViewInit} from "#angular/core";
#Component({
moduleId: module.id,
selector: 'home',
templateUrl: '../views/home.html',
styleUrls: ['../../public/css/home.css']
})
export class HomeComponent implements AfterViewInit {
ngAfterViewInit(): void {
jQuery.getScript('public/js/home.js');
}
}
I hope this helps somebody with the same problem.

Angular 2 template convention

For every example I come across in Angular 2 the template lives in the component decorator.
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: '<h1>Hello world</h1>'
})
export class AppComponent { }
Is this the correct convention? When templates become complex I would imagine this syntax becomes cumbersome.
I have tried using templateUrl instead of template. But as I understand it Angular will then load the template via ajax. (Slightly related, but since I've updated to 2.0.0-rc.3 templateUrl no longer seems to be working, but maybe I'm doing something wrong).
What is the best way to handle templates?
You can use templateUrl in rc3; see below the template code for a basic component:
import { Component, OnInit } from '#angular/core';
#Component({
moduleId: module.id,
selector: 'app-my-component',
templateUrl: 'my-component.component.html',
styleUrls: ['my-component.component.css']
})
export class MyComponentComponent implements OnInit {
constructor() {}
ngOnInit() {
}
}
templateUrl should be used as a normal practice to keep the component definition clean.
The official ng2 tutorial will help clarify some of the base-questions , it helped me : https://angular.io/docs/ts/latest/tutorial/
From the Angular2 style guide
| Do extract templates and styles into a separate file, when more than 3 lines.
The upcoming offline template compiler will inline templates linked by templateUrl. There are also Gulp tasks available to do this already.
The official style guide
https://angular.io/styleguide#!#05-04
may suggest you to isolate styles and templates into different files.
But at the same time if you are shipping a component the single component file will make it easy and independent. So it is about your requirement. If you want your component to be reused independently this approach where embedding the template file into the component would win. And in the end it's your choice.
Hope this help you. Thank you.
Template url should be used for writing html code because of two reasons:
1. Seperation of concerns : A convention used for project development.
2. Easy debugging: in various IDE's you can use html lint plugins so as to find issue in html.
If your html is of one or two line then you can use it inline.

Categories

Resources