Angular 2 Execute JS from file using AfterViewInit - javascript

Quite new to Angular 2, and after looking around for few hours I'd like to have some help.
I have a JS file with some generic functions. For example:
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
This file contains in fact way more code. As you can imagine, I'd like to enable tooltips of all components. I can't simply include this file in index.html because subcomponents aren't present (yet) when the file is loaded.
After some digging, afterViewInit() came up. This post suggests to copy/paste JS code into ngAfterViewInit(). That's the ugly way (in my opinion)...
So here I come with 2 related questions:
1# Is there a way to execute JS code when a child component is loaded? For example, something like:
// In app.component.ts
ngAfterChildComponentLoaded(){
// JS code here
}
This solution is quite interesting because I'm not forced to implement ngAfterViewInit() with the same content in all my components. But is it possible?
2# Is there a way to import JS code instrad of copy/paste it into ngAfterViewInit()? I don't want copy/paste 300 lines of JS code into 15 differents components (for obvious reasons).
Thanks a lot for your help!

See the following for how to get external js files for a particular component in angular 2/4:
import { Component, OnInit , AfterViewInit} from '#angular/core';
import { Router } from '#angular/router';
declare var $: any;
#Component({
moduleId: module.id,
selector: 'dashboard',
templateUrl: './dashboard.html',
styleUrls: ['./dashboard.css']
})
export class DashboardComponent implements OnInit,AfterViewInit {
constructor() {}
ngOnInit() {
}
ngAfterViewInit(){
$.getScript('assets/assets/build/js/custom.min.js');
}
}

Got a less-ugly solution, if someone has a better one I'll gladly accept his answer!
ngAfterViewInit(){
$.getScript('assets/js/myscript.js', function(){});
}

Related

How to use cool-ascii-faces in Angular?

Just for fun, I'd like to use the javascript library cool-ascii-faces in my Angular application. I followed the instructions in the blog "How to use external JavaScript Libraries in Angular 8".
I did the following things:
installed cool-ascii-faces per npm in my Angular project under node_modules.
In angular.json, added these two scripts to both build and test section:
"scripts": [
"./node_modules/cool-ascii-faces/cli.js",
"./node_modules/cool-ascii-faces/index.js"
]
My app.components.ts looks like this:
import { Component, OnInit } from '#angular/core';
declare var coolFace: any;
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent implements OnInit {
ngOnInit(): void{
console.log(coolFace());
}
}
But, in the console I only see: ReferenceError: coolFace is not defined. What have I done wrong?
Thank #Andres O. Serrano for his advice. I tried both approach, neither worked.
But I came up with another solution. Simply store all the ascii faces in a Json file under /asset. Then follow the instruction in the blog "How to Read Local JSON file in Angular". It works like a charm. Thanks!

Angular wrapper of JS library doesn't load styles

I want to use this library https://bootstrap-datepicker.readthedocs.io/en/latest/markup.html#date-range in my application. But it has to be angular component so for the first time in my short career I wanted to create wrapper of library but I think I did something wrong becouse It doesn't looke like original picker.
This is how it should looks like:
And this is how it looks like as my angular component:
Also when I want to select only month or year it looks weird:
Ok so now time to see my component code:
import {AfterViewInit, Component, ElementRef, Input, OnInit} from
'#angular/core';
import 'bootstrap-datepicker';
declare var $;
#Component({
selector: 'cb-daterangepicker',
templateUrl: './daterangepicker.component.html',
styleUrls: ['./daterangepicker.component.scss']
})
export class DaterangepickerComponent implements OnInit, AfterViewInit {
#Input()
datepickerOptions: DatepickerOptions;
constructor(private elementRef: ElementRef) {
}
ngOnInit() {
}
ngAfterViewInit(): void {
// $(this.elementRef.nativeElement).datepicker();
$('.input-daterange input').each(function() {
$(this).datepicker('clearDates');
});
}
}
As You see there is no for example selection of range, or just start and end dates, it simply looks different so I thought it becouse not loaded styles but I might be wrong. I need Your help Guys, maybe my wrapper isn't correctly done?
*Network console with styles:
Addin styles to index.html and angular.json helped with some things:
But still range between dates is not highlighted..
Are you sure that bootstrap is correctly loaded ? you have to check this first and you have to check if the css for the library is loaded afterwards.
try to check that with the browser network console :)
othewise try to call the library style with the cdn :
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css

How to access external javascript file from angular 2 component

I am very new to angular and front end web development, so maybe i am missing something
basic but i did not succeed to search a solution for that issue.
according to that answer: Call pure javascript function from Angular 2 component
and following that example
I am trying to import external .js file to my angular component:
import '../../../src/Plugin/codemirror/mode/custom/custom.js'
#Component({
selector: 'txt-zone',
templateUrl: 'app/txtzone/Txtzone.component.html',
styleUrls: ['app/txtzone/TxtZone.css'],
})
the path is the correct relative path, i know that because if it loads diractly from the url text box via the browser [http://localhost:50371/src/Plugin/codemirror/mode/custom/custom.js]
i can see the file content...
this is the exception that the chrome debugger is throwing:
zone.js:2263 GET
http://localhost:50371/src/Plugin/codemirror/lib/codemirror 404 (Not
Found)
as you can see the path was changed (don`t understand why?)
1. how can i solve this issue?
2. why the path of the .js file is not the referenced path?
3. maybe there is a better way to load external .js file into my component?
it looks quite trivial question but after hours of searching i could not find any answer.
A simple way to include custom javascript functions in your Angular 4 project is to include the item in your assets folder, and then use require to import it into your component typescript.
src/assets/example.js
export function test() {
console.log('test');
}
src/app/app.component.ts
(before #Component(...))
declare var require: any;
const example = require('../assets/example');
(inside export class AppComponent implements OnInit { ...)
ngOnInit() {
example.test();
}

Using JQuery Plugins in Angular 4 Applications

So I am currently trying to use some jquery plugins like Magnific-Popup etc in my Angular 4 application but I'm having some trouble. I installed jquery by doing npm install --save-dev #types/jquery in my terminal and that worked fine, but I'm having trouble getting the actual plugins to work. This is what I tried initially,
#Component({
selector: 'app-showcase',
templateUrl: './showcase.component.html',
styleUrls: ['./showcase.component.css']
})
export class ShowcaseComponent implements OnInit {
#ViewChild("elementRef") elref2: ElementRef;
constructor(private elRef: ElementRef) { }
ngOnInit() {
jQuery(this.elref2.nativeElement).magnificPopup();
}
ngAfterViewInit() {
}
In order to get typescript to recognize the magnificPopup() function, I tried importing the scripts from the magnificPopup documentation into my index.html (at the bottom of the body tag), but as far as I can tell that is not working. Webstorm says "can not resolve file jquery.magnific-popup.js". I'm also loading the jquery.min script as well, and that seems to work fine.
I also tried running npm-install magnific-popup, but that also failed. Additionally, I tried adding the script into the angular.JSON file but to no avail.
I guess what I'm asking is, what is and how can I go about installing and using a third-party jquery plugin like magnific-pop up into my angular 4 application?
Thanks, any help is appreciated.
I have an Angular project where I need to use (for now) a jquery dependent plugin (nanoscroller). I use angular-cli to do all my build processes and my angular-cli.json file has the following under the "scripts" property:
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/nanoscroller/bin/javascripts/jquery.nanoscroller.js"
]
Then I use the plugin as follows:
import { AfterViewInit, Component, ElementRef, OnDestroy, Renderer, ViewChild } from "#angular/core";
declare var jQuery: any;
#Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"]
})
export class AppComponent implements AfterViewInit {
layoutMenuScroller: HTMLDivElement;
#ViewChild("layoutMenuScroller") layoutMenuScrollerViewChild: ElementRef;
constructor() {
}
ngAfterViewInit() {
this.layoutMenuScroller = <HTMLDivElement>this.layoutMenuScrollerViewChild.nativeElement;
jQuery(this.layoutMenuScroller).nanoScroller({ flash: true });
}
// etc..
}
Perhaps you can adopt this to your use-case.

Title service in angular2

I have used the Tile service of Angular, and title are getting set successfully.
Here is the code:
import { Component, OnInit } from '#angular/core';
import { Title } from '#angular/platform-browser';
#Component({
selector: 'app-homepage',
templateUrl: './homepage.component.html',
styleUrls: ['./homepage.component.css']
})
export class HomepageComponent implements OnInit {
constructor(private titleService: Title) { }
ngOnInit() {
this.titleService.setTitle('homepage first title');
}
}
but the problem is that when i check the title change through "view page source", none of the changes are getting reflected and the default title in index page is showing , what can i do to resolve this.
View page source is the plain index.html source file (like you have it on your/server file system). No JavaScript is executed or anything, so obviously nothing will show.
If you would like to have that the application is already compiled, take a look at NgUniversal, to leverage server side rendering. Not sure if that will work for your use-case though.

Categories

Resources