Use jQuery with Angular

yarn add jquery
yarn add @types/jquery --dev

angular.json

"scripts": [
  "node_modules/jquery/dist/jquery.min.js"
],

app.component.html

<div #divBox style="width: 40px;height: 40px;background-color: blue;">

</div>

app.component.ts

import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
import * as $ from 'jquery';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  title = 'myapp';
  @ViewChild('divBox') divBox: ElementRef;

  ngAfterViewInit(): void {

    setTimeout(() => {
      $(this.divBox.nativeElement).hide();
    }, 3000);

  }
}

References
https://www.npmjs.com/package/jquery
https://stackoverflow.com/questions/42919161/selecting-template-element-and-passing-to-jquery-in-angular-2-component
https://stackoverflow.com/questions/30623825/how-to-use-jquery-with-angular

Best approach for deploying Angular app in Spring Boot

Avoid @EnableWebMvc

WebConfig

package net.pupli.web_server.config;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.resource.EncodedResourceResolver;
import org.springframework.web.servlet.resource.GzipResourceResolver;
import org.springframework.web.servlet.resource.PathResourceResolver;

import java.io.IOException;
import java.util.List;

@Configuration
@EnableAutoConfiguration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        // enable cache for static files
/*        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(3600 * 24 * 7);*/

        // serve pre gzip files in static folder
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(3600 * 24 * 7)
                .resourceChain(false)
                .addResolver(new EncodedResourceResolver());

        registry.addResourceHandler("/index.html")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(0);
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/notFound").setViewName("forward:/index.html");
    }

    @Bean
    public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
        return container -> {
            container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
                    "/notFound"));
        };
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
        converters.add(gsonHttpMessageConverter);
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

 

References
https://stackoverflow.com/questions/44692781/configure-spring-boot-to-redirect-404-to-a-single-page-app
https://stackoverflow.com/questions/39331929/spring-catch-all-route-for-index-html/42998817

Best approach for deploying Angular app in Express

This approach serves pre gzipped Angular files and sets client-side caching for static files to 1 year

var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mime = require('mime-types');
//var compression = require('compression');
var expressStaticGzip = require("express-static-gzip");
var app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
//app.use(compression());
app.use("/", expressStaticGzip(path.join(__dirname, 'public'), {
    maxAge: "365d",
    setHeaders: function (res, path) {
        if (mime.lookup(path) === 'text/html') {
            res.setHeader('Cache-Control', 'public, max-age=0')
        }
    }
}));
//app.use(express.static(path.join(__dirname, 'public'), {maxAge: 31536000}));
app.get('*', function (req, res, next) {
    var file = path.join(__dirname, 'public', 'index.html');
    res.sendFile(file);
});
module.exports = app;

gzip Angular files after build

npm i gzipper -g

or locally to devDependencies

npm i gzipper -D

use gzipper with your build commands (e.g. Angular CLI)

"scripts": {
    "build": "ng build && gzipper --verbose ./dist"
  }

compress files to a certain directory ./gzipped

"scripts": {
    "build": "ng build && gzipper --verbose ./dist ./gzipped"
  }

build.bat

ng build --prod --aot && gzipper --verbose ./dist

References
https://www.npmjs.com/package/gzipper

Deploy Angular app to Express

Angular

ng build --prod --aot

app.js in express

var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var compression = require('compression');

var app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(compression());
app.use(express.static(path.join(__dirname, 'public'), {maxAge: 31536000}));


app.get('*', function (req, res, next) {
    var file = path.join(__dirname, 'public', 'index.html');
    res.sendFile(file);
});

module.exports = app;

 

Find inner elements using query in Angular Animation

@Component({
  selector: 'inner',
  template: `
    <div [@queryAnimation]="exp">
      <h1>Title</h1>
      <div class="content">
        Blah blah blah
      </div>
    </div>
  `,
  animations: [
   trigger('queryAnimation', [
     transition('* => goAnimate', [
       // hide the inner elements
       query('h1', style({ opacity: 0 })),
       query('.content', style({ opacity: 0 })),

       // animate the inner elements in, one by one
       query('h1', animate(1000, style({ opacity: 1 }))),
       query('.content', animate(1000, style({ opacity: 1 }))),
     ])
   ])
 ]
})
class Cmp {
  exp = '';

  goAnimate() {
    this.exp = 'goAnimate';
  }
}

References
https://angular.io/api/animations/query