conditional script in angular index.html - javascript

I have this angular project and then index.html is the main entry point of the application like any other angular project , it contains the links.
As you can see on the html below there is an interpolation which is the ${environment.code} that is coming from the environment config.
The value of google tag manager id should be the value of ${environment.code} which is different for dev, staging and prod.
The problem is environment.code is not being accesssible in the index.html (tried different ways)
is there a way we can modify the index.html or at least modify the google tag manager id value for different environments? Thanks,
#index.html code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Cache-Control" content="max-age=0, must-revalidate"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Expires" content="0" />
<title>m</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="sec-validation" content="d1343a3ae51-8f7b-4038-bfc8-c56565485456547a4d">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id=${environment.code}'+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer',environment.code);</script>
<!-- End Google Tag Manager -->
</head>
<body class="mat-typography dx-viewport">
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=${environment.code}"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<app-root></app-root>
</body>
</html>
#main.ts code
import { enableProdMode } from '#angular/core';
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
#environment code
export const environment = {
production: false,
appName: 'My App',
code: 'AGRTSRS-GMSDS'
};

It is not possible to use env files in index.html, but you can provide a separate index file for each environment:
"configurations": {
"production": {
"index": {"input": "src/prod.index.html", "output": "index.html"}
},
"staging": {
"index": {"input": "src/staging.index.html", "output": "index.html"}
}
}
You could write schematics to extract env data and patch index.html but it seems to be too complicated for the task.
Another way is to use multiple JSON configuration files, you can import these files into env file and also you can write post-build script that patches index.html using apporpriate JSON file.

Related

string interpolation in angular index html

I have this angular project and then index.html is the main entry point of the application like any other angular project , it contains the links.
As you can see on the html below there is an interpolation which is the ${environment.code} that is coming from the environment config.
The value of google tag manager id should be the value of ${environment.code} but when we check the value in the browser when we run and inspect element it did not get the value of the env code . Any idea how we can solve this one guys ? I already tried dom manipulation, string interpolation etc but nothing seems to work. Thanks for any help and ideas much appreciated.
#index.html code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Cache-Control" content="max-age=0, must-revalidate"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Expires" content="0" />
<title>m</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="sec-validation" content="d1343a3ae51-8f7b-4038-bfc8-c56565485456547a4d">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id=${environment.code}'+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer',environment.code);</script>
<!-- End Google Tag Manager -->
</head>
<body class="mat-typography dx-viewport">
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=${environment.code}"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<app-root></app-root>
</body>
</html>
#main.ts code
import { enableProdMode } from '#angular/core';
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
#environment code
export const environment = {
production: false,
appName: 'My App',
code: 'AGRTSRS-GMSDS'
};
Write iframe src as [src]= for {} to be evaluated.

How to change location of favIcon in angular 11 based on some condition

I am using Angular 11 in which I am able to load/show the favicon which is located in the src folder. But my requirement is to make favicon configurable if I have put its location in the config variable so that it would take the location of favicon based on the value which I have provided in the config file. Note: we are changing the config variable only before deployment.
I have tried using many things but nothing is working for me. Only I am able to get the favicon which is located in the source folder.
In app.component.html
<head>
<meta charset="utf-8">
<title>Test</title>
<base href="./">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" id ="favIcon" href="assets/{{favIcon}}">
</head>
<body>
</body>
In app.component.ts file, favIcon variable is set to images/favicon1.ico
We have tried changing this by JavaScript using document selector in app.component.ts
this.favicon = document.getElementById('favIcon');
this.favicon.href = this._sanitizer.bypassSecurityTrustUrl("assets/images/rdh-favIcon.ico");
could you please provide any solution so that I can use a different favicon from a different location?
In angular.json
"assets": ["src/favicon.ico",
"src/assets"],
In your app.component.html
<link rel="icon" id ="favIcon" type="image/x-icon" href="favicon.ico">
In your app.component.ts
export class AppComponent {
favIcon: HTMLLinkElement = document.querySelector('#favIcon');
changeIcon() {
this.favIcon.href = 'https://www.google.com/favicon.ico';
}
}
For Angular 12.x replace
favIcon: HTMLLinkElement = document.querySelector('#favIcon')
with
favIcon: any = document.querySelector('#favIcon')
Don't forget to add a button somewhere in your app.component.html that excutes this changeIcon() function.
i.e.
<button (click)="changeIcon()">Change favicon</button>
Hope this helped.

How to include jquery plugin in ionic 3

I'm trying to implement jQuery FloatLabel in my ionic app -> https://github.com/m10l/FloatLabel.js/tree/master
I used that plugin because that plugin also was implemented in a web version, so to be uniform in design.
I included that inside src/index.html with jquery
<link href="assets/js/jquery.FloatLabel/jquery.FloatLabel.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="assets/js/jquery.FloatLabel/jquery.FloatLabel.js"></script>
I want to execute this script on page load
$( '.js-float-label-wrapper' ).FloatLabel();
Here's my src/index.html code
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Ionic App</title>
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
<link rel="manifest" href="manifest.json">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<meta name="theme-color" content="#4e8ef7">
<!-- add to homescreen for ios -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- cordova.js required for cordova apps -->
<script src="cordova.js"></script>
<link href="build/main.css" rel="stylesheet">
<link href="assets/js/jquery.FloatLabel/jquery.FloatLabel.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="assets/js/jquery.FloatLabel/jquery.FloatLabel.js"></script>
<script type="text/javascript">
$( '.js-float-label-wrapper' ).FloatLabel();
</script>
</head>
<body>
<!-- Ionic's root component and where the app will load -->
<ion-app></ion-app>
<!-- The polyfills js is generated during the build process -->
<script src="build/polyfills.js"></script>
<!-- The vendor js is generated during the build process
It contains all of the dependencies in node_modules -->
<script src="build/vendor.js"></script>
<!-- The main bundle js is generated during the build process -->
<script src="build/main.js"></script>
</body>
</html>
It works on web version but not in ionic. How do I implement that on ionic?
I want it like this fiddle -> https://jsfiddle.net/acrmktq3/
link jquery.js in your index.html:
<script src="assets/js/jquery-3.2.1.min.js"></script>
run in node:
npm install jquery
and import it in your page like:
import * as $ from "jquery";
Try adding your JavaScript code in the bottom of your body like this:
<body>
<!-- Ionic's root component and where the app will load -->
<ion-app></ion-app>
<!-- The polyfills js is generated during the build process -->
<script src="build/polyfills.js"></script>
<!-- The vendor js is generated during the build process
It contains all of the dependencies in node_modules -->
<script src="build/vendor.js"></script>
<!-- The main bundle js is generated during the build process -->
<script src="build/main.js"></script>
<script type="text/javascript">
$( '.js-float-label-wrapper' ).FloatLabel();
</script>
</body>
You're addng it before your app initialization, the main.js wasn't even loaded and you've already executed your code, so using it on the bottom of your code should do the trick.
Also, have you ever tried using this FloatLabel in a Ionic application? Since the page may not be loaded and the code already had been executed you need it to be more "Angular way". You can use it inside the component that's having the floating label, just use this to be able to use JQuery inside your component:
declare var $: any; // declare this bellow your page imports to be able to use jQuery
Or you can try Ionic floating Label, so there's no need to have JQuery and other library inside your project, even if it's not "uniform" design
<ion-item>
<ion-label color="primary" floating>Floating Label</ion-label>
<!-- Use the floating attribute to have your label to float when you focus on the input -->
<ion-input></ion-input>
</ion-item>
Hope this helps.

How to import .js file to .ts in ionic?

I have create a .js file inside my /www/js/N.js after that I include in the index.html like src="assests/js/getImage.js"> and the script is before the build/polyfills.js
After that, what should I do to get my .js file working ??
here is my source code
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Ionic App</title>
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#4e8ef7">
<!-- add to homescreen for ios -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- cordova.js required for cordova apps -->
<script src="cordova.js"></script>
<script src="assets/js/getImage.js"></script>
<!-- un-comment this code to enable service worker
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.error('Error', err));
}
</script>-->
<link href="build/main.css" rel="stylesheet">
</head>
<body>
<!-- Ionic's root component and where the app will load -->
<ion-app></ion-app>
<!-- The polyfills js is generated during the build process -->
<script src="build/polyfills.js"></script>
<!-- The vendor js is generated during the build process
It contains all of the dependencies in node_modules -->
<script src="build/vendor.js"></script>
<!-- The main bundle js is generated during the build process -->
<script src="build/main.js"></script>
</body>
</html>
May I know is there any import js to ts tutorial available ??
I found a lot on youtube but none of them meet my requirement. !!
Thanks in advance, please help me. Thanks !

Calling method from compiled js file

I seem to be unable to call a method from a JS package from one of my other files (all.js). I am using Laravel 5.4, VueJS2, and VueRouter. This is an SPA where Laravel serves as a backend.
I get the following error: TypeError: $.LoadingOverlay is not a function
I am utilizing web pack and compiling the assets like this:
mix.js([
'resources/assets/js/bootstrap.js',
'resources/assets/js/helpers.js',
'././node_modules/gasparesganga-jquery-loading-overlay/src/loadingoverlay.min.js',
'resources/assets/js/app.js',
'././node_modules/moment/min/moment.min.js',
'././node_modules/moment-duration-format/lib/moment-duration-format.js',
], 'public/js/all.js').version();
The file containing the code I am trying to pull in is the loadingoverlay.min.js file. The file that is referencing it is right underneath it (app.js).
My app.js file:
import Vue from 'vue';
import VueRouter from 'vue-router';
var $ = require('jquery');
Vue.use(VueRouter);
const routes = [
.. routes here
];
const router = new VueRouter({
routes,
mode: 'history',
});
router.beforeEach((to, from, next) => {
console.log('Entering route');
$.LoadingOverlay('show');
next();
});
router.afterEach((to, from) => {
console.log('Entered route');
$.LoadingOverlay('hide');
})
const app = new Vue({
router
}).$mount('#app');
The blade file that is responsible for pulling in the compiled assets:
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="author" content="">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="{{ mix('css/all.css') }}">
<meta name="csrf-token" content="{{ csrf_token() }}"/>
</head>
<body>
<div id="app">
<section class="container">
<div>
<router-view></router-view>
</div>
</section>
</div>
<script src="{{ mix('js/all.js') }}"></script>
</body>
</html>
Interestingly enough, I am able to call the method from that file from my blade page by adding <script></script> tags after the all.js file is pulled in, and calling it from there.
Any ideas on why this may be happening?
Exactly as it says, because $.LoadingOverlay is not a function.
The jQuery compiled into your all.js via webpack (done via nodejs) will cause the $ = require('jQuery') to be different than the one globally exposed via window.$
window.$ is referencing jQuery 1.11.0 and the one inside your app.js is referencing the jQuery built with webpack.

Categories