Archive for the 'Ionic' Category

September 7th, 2022
4:10 pm
Running Legacy Places Guide under Windows 11 for reference

Posted under CouchDB & Hosting & Ionic & Knowledge Base & Networks & PrimeNG & Web & Windows 11
Tags ,

Having got CouchDB working under Windows 11 with the legacy places data as per this post here, I then wanted to run the legacy places angular and ionic apps if possible, just for reference and to consider my options going forward.

The angular app was in v6.1.7 which I did not want to revisit and upgrade. Similarly, the ionic app was an earlier legacy version which could be tricky to reinstate under windows 11.

However, I did have already built distributions for both apps, and both were able to run successfully under Windows 11 via http-server without having to install anything else. For angular I used the existing build under the dist subdirectory, and for Ionic I the build is under the www subdirectory. Note that whilst the index.html for the Ionic version did specify that cordova.js was required, and caused a load error in the web console, this was not an issue when using from a browser as it was not needed.

I did want to be able to run them remotely as well, from other PCs and mobiles. I tried installing the distributions under Zen hosting, with remote access to CouchDB running on the local PC. However, this would not run under HTTPS as it meant having mixed content – the access to CouchDB was not HTTPS and I did not want to go to the trouble of installing a self signed cert locally to get it all to work – this excercise was not worth the effort. I could not find an easy way under Zen cpanel of allowing just this app to be HTTP only, with everything else defaulting to HTTPS. If I turned off forced defaulting to HTTPS in cpanel, the app worked fine under HTTP but other access was also allowed to be HTTP only which I did not like, so I dumped the idea of hosting under Zen directly. I did hit a spate of nasty looking cpanel issues when I did this and for a while thought I had broken the domain/ssl/cpanel access entirely whilst messing with domain/alias/redirect settings in cpanel, but in the end it all worked fine again.

I therefore continued to run/host locally via http-server. I did want to be able to potentially remote boot my local PC via Fritz and access the app from anywhere, which would mean auto running the http-servers at boot time. The easiest way to do this turned out to be to use the windows task scheduler, which unlike services can run batch files without any other tools such as srvany which is commonly used to do this for services. Whilst the scheduler is often used with time based triggers, it is perfectly possible to specify a trigger as ‘run at boot time’. I also specified that it should run without any user logged in, therefore with local access only/no user authentication. This worked fine and I could boot the PC and then immediately access the places apps from a mobile without logging in.

Another trick needed was to add some remote port sharing in the Fritz box for both apps, via my static IP addresses. When doing this I also had to add a port share for the CouchDB access, otherwise CouchDB also complained about mixing private CORS stuff with the remote access. Once I did this, and changed the app config to use the remote URL for CouchDB access, it all worked fine. Fortunately, I could also continue to access the same apps locally on the hosting PC even though they were still using the remote URL for CouchDB access – it all worked fine.

I then set up redirects under cpanel from Zen to make the app access look a bit more friendly with salient soft urls, and this all ran fine.

 

Comments Off on Running Legacy Places Guide under Windows 11 for reference

June 6th, 2017
5:58 pm
Angular/Ionic–externalising application configuration

Posted under Angular & Ionic & TypeScript
Tags , , , ,

Key Goals

  1. The primary goal is to completely decouple configuration data from the build deployment. This is a key requirement in an enterprise setting, not least because it is vital that the very same build can be tested and signed off in a number of different development and test environments pointing at different server infrastructure.  If a different build was needed for each environment, there is always the risk of an incorrect build, so technically the final production build has never been tested and could break. A good discussion on this may be found on The Twelve Factor App site here.
  2. Upon investigating a pattern for this in Ionic and Angular, I found numerous posts citing different ways around the problem, some appearing quite complex. I was left feeling that this need was not something that had been baked in to the Framework design as a first class citizen – it was certainly not an up front and clear pattern in the documentation. Therefore I wanted a reusable pattern to use as a standard for all my Angular development.
  3. I am using angular-cli with webpack, which is the recommended approach. This produces simple static deployment bundles which are web server agnostic – just an html file which loads one or more js bundles, plus assets such as fonts and images. The pattern for externalising configuration aims to fit in with this and makes no assumptions about the ability to build configuration data dynamically server-side or inject configuration related information into the web server. For example, a common pattern when using Apache Tomcat with Java applications is to inject a configuration location as a JVM parameter into tomcat, which is used later server-side to access the configuration dynamically. We make no assumptions here about the ability to do this kind of trick – any such mechanisms (discussed further below) would be an extension to the pattern for a particular server.
  4. An important goal of the pattern is that it should be testable, i.e. we use dependency injection to inject configuration into the classes that use it, (in our case via a service). This allows unit tests to inject test configuration as required.
  5. The pattern also supports offline use e.g. in an Ionic application. If, as some solutions advocate, the configuration was loaded via an HTTP service in javascript code, this would not work offline with Ionic. The challenge that remains is how and where the configuration would be located in an Ionic deployment, but that is a question for another day and further invesigation.

 

Solution Overview

  1. After a fair amount of investigation I settled on a fairly simple pattern as per this post here. This stackoverflow comment refers to the same technique.  I adapted the technique for my situation – the key points are as follows, and a code sample is shown below.
  2. The basic idea is to load configuration data as a Json object literal from a .js file. This is done by a <script> tag in index.html, prior to the loading of the webpack bundles, which loads the configuration typically as a file from a known location, where the src of the <script> tag is deemed not part of the build.
  3. Whilst this would typically be a location on the same server such as the root directory where index.html is located, it does not have to be, and could equally well be loaded from another server over http. The key point is that the precise src for the script tag is a contract between index.html and any deployment/configuration management software. For example, the configuration file might be dynamically created by Ansible or similar, or the configuration might not be a file at all, and could be dynamically created server side via a web service. These possibilities are all extensions to the basic pattern and depend on the particular web servers and deployment techniques in play.
  4. When running in development mode using ng serve, the bundles are created in memory and no files exist. Therefore this mechanism will not work as the <script> tag will not load anything. We therefore provide a means of having default configuration in the code which will be overridden by the above configuration file if present. If the configuration file is not present (ng serve in dev mode) you will get a 404 for the script tag on the console, which can be ignored.
  5. When running in development mode using files (e.g. via lite-server using  ng build –watch and running lite-server from the dist subdirectory), a config file can be used in the normal way to override the default config if desired.
  6. The default configuration object is exported as a constant from the appropriate environment file, e.g. environment.ts. Whilst there could be default settings in environment.prod.ts, the default is typically set to null in this case so that a configuration file is always used.
  7. The structure of the configuration data is typed via an AppConfig interface which is used everywhere the data is loaded or referenced. In simple cases the configuration data may be just properties of the root AppConfig object. However in more complex cases the object graph could be extensive.
  8. The configuration file loads the configuration object into a global variable which is then read by the AppConfigService, and if present overrides the default configuration. Object.freeze() is used (along with readonly properties on the AppConfig interface) to make the configuration data immutable. Whilst in theory it may be possible to inject the resulting configuration as a constant using a value provider, when I tried this (with the latest Angular 4) I hit a variety of intermittent compile/build errors citing ERROR in Error encountered resolving symbol values statically. In the end I went with an injected configuration service, which consuming classes set up as a getter to allow convenient access.
  9. The AppConfigService loads the global configuration variable via a casted reference to the window object. I tried to get this to work via a declare to reference it as an external object but again I hit compile errors when doing so.

 

Example Code Listings

 

index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Places Admin</title>

<base href=”/”>

<meta name=”viewport” content=”width=device-width, initial-scale=1″>
<link rel=”icon” type=”image/x-icon” href=”favicon.ico”>

<script type=”text/javascript” src=”appConfig.js”></script>

</head>
<body>
<app-root>Loading…</app-root>
</body>
</html>

appConfig.js – external configuration file.

// Application Configuration
var salientSoft_appConfig = {
  appTitle: "The Places Guide",
  apiBase: "http://localhost:5984/places-guide/",
  messageTimeout: number = 3000
};

environment.ts

// The file contents for the current environment will overwrite these during build.
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
// The list of which env maps to which file can be found in `.angular-cli.json`.

import {AppConfig} from ‘../config/app-config’;

export const environment = {
production: false,
};

export const defaultAppConfig: AppConfig = {
appTitle: ‘The Places Guide’,
apiBase: ‘http://localhost:5984/places-guide/’,
messageTimeout: 3000
};

environment.prod.ts

import {AppConfig} from '../config/app-config';

export const environment = {
production: true
};

export const defaultAppConfig: AppConfig = null;

appConfig.ts – config file interface

/* Root application configuration object
   This encapsulates the global config json properties.
   These must match what is in the actual config file, normally /appConfig.js.
 */
export interface AppConfig {
    readonly appTitle: string;
    readonly apiBase: string;
    readonly messageTimeout: number;
}

app-config.service.ts

import {Injectable} from '@angular/core';
import {AppConfig} from './app-config';
import {defaultAppConfig} from '../environments/environment';

@Injectable()
export class AppConfigService {
private _appConfig: AppConfig;
buildConfig(): AppConfig {
const appConfig: AppConfig = (<any>window).salientSoft_appConfig || defaultAppConfig;
return Object.freeze(appConfig);
}
constructor() {
this._appConfig = this.buildConfig();
}
get(): AppConfig {
return this._appConfig;
}
}

app.component.ts – example configuration consumer

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

constructor(
private appConfigService: AppConfigService
) {}

public get appConfig(): AppConfig {return this.appConfigService.get(); }

ngOnInit(): void {
document.title = this.appConfig.appTitle;
}

No Comments »

May 10th, 2017
11:12 am
Ionic Vs NativeScript for mobile application development

Posted under Ionic & NativeScript
Tags

NativeScript is the newer kid on the block – some of its key differences are as follows:-

  1. NativeScript uses its own XML based element tags which are compiled to actual native elements in the deployed application.
  2. This means that your view templates do not use HTML or ‘normal’ css – the elements and attributes are different and therefore there is a learning curve here as you have to learn all the new markup.
  3. Native feature access such as cameras etc. is easier with NativeScript – with Ionic, often plugins for Cordova are needed, however this appears set to improve fairly soon.
  4. You still develop with Javascript or TypeScript, and you can use Angular for development. However, I am not clear on how all the dynamic features/specific attributes of Angular which target the HTML DOM will fit in and work with the NativeScript XML elements – I would expect there to be some compromises here on what you can do. NativeScript does support dynamic creation of elements, but I would not expect all this to work in the same way as adding dynamic html/changing innerHTML with Angular for example.
  5. For development testing, you use an Android or IOS emulator e.g. under Windows. For android debugging, you can attach the Chrome developer tools to debug.
  6. From the perspective of being a web developer, it looks like Ionic is easier and more familiar in use.
  7. The key feature with NativeScript is that it does give you true native components, and the apps run faster as they are native. However the app size for download/install is also much larger.
  8. It does correctly claim to support all its target platforms from a single code base – note that all the targets run native applications.
  9. Therefore note that it does not create a web app of any kind. Therefore when support for Windows comes out sometime soon, this will be a native application running on Windows.

There are a number of pros and cons and no shortage of discussion on line, and the following posts do some in-depth comparison on this:-

http://pointdeveloper.com/category/nativescript/

http://pointdeveloper.com/nativescript-vs-ionic-framework-pros-cons/

http://stackoverflow.com/questions/40819520/hybrid-app-ionic-vs-nativescript

http://www.discoversdk.com/blog/ionic-2-vs-reactnative-vs-nativescript

https://www.thepolyglotdeveloper.com/2015/11/nativescript-vs-ionic-framework-should-you-switch/

No Comments »

May 10th, 2017
8:34 am
Angular 2 and Ionic – Builders/ Package Managers/ Bundlers/ Task Runners

Posted under Angular & Ionic
Tags ,

The landscape in this regard is pretty complex with a number of choices out there.

This StackOverflow post discusses the functionality and pros/cons of the alternatives and is helpful in gaining an idea of what they all actually do!

I was keen to pick tools that met my needs, especially re the ability to build apps from separate shared components, but did not want to over complicate things by using tools that I did not really need.

My conclusion from the above and all the comments is that for the moment all my need can be met by just sticking with Webpack (in conjunction with Angular CLI and Ionic CLI), and not venturing to use tools such as Gulp on top as I don’t really need to.

This is good as webpack is the standard for Angular and Ionic.

No Comments »

May 8th, 2017
12:15 pm
Ionic error on startup – ionic Error: ENOENT: no such file or directory

Posted under Ionic
Tags , ,

The cause of this is not immediately obvious, but it blocked startup via ionic serve – the error continues to cite a template error of some kind.

The actual issue is an invalid file path on the templateUrl attribute of the @Component({ decorator of the relevant component mentioned in the error. I found a variety of different file paths used – some with no path and just the filename, some with “./” on the front, and the offending one had a prefix of “src/” which caused the failure.

Just correcting the file path on the attribute fixes the problem.

No Comments »

April 27th, 2017
8:09 pm
Webstorm 2017.1 update failure due to Kaspersky false detections

Posted under Ionic & Kaspersky & WebStorm
Tags , ,

1/ I took the latest 2017.1 upgrade when offered by Webstorm. This upgrade results in the following version:-

WebStorm 2017.1.2
Build #WS-171.4249.40, built on April 25, 2017
Licensed to Steve Woodley
You have a perpetual fallback license for this version
Subscription is active until April 9, 2018
JRE: 1.8.0_112-release-736-b21 x86
JVM: OpenJDK Server VM by JetBrains s.r.o
Windows 7 6.1

During the upgrade, Kaspersky complained that E:\Program Files (x86)\JetBrains\WebStorm 2017.1\jre32\bin\unpack200.exe contained a trojan malware virus. This caused the upgrade to fail.

I checked this online and discovered that Webstorm often gets cited as giving false malware positives, all of which are false. I was happy to allow this to proceed as a Kaspersky exception.

This Kaspersky forum post gives details on what to do (including disabling file antivirus). It then says to add a file exception rule for the file – the instructions for doing this may be found here. Whilst the link is for a 2014 version of Kaspersky, it is similar enough to be correct with the current version as at 2017, with just a few textual prompt/description differences. Note that I added the full file name, but did not enter a value for the file/folder name mask ref the “virus encyclopedia” quoted in the instructions. (I wouldn’t have known what to enter there anyway!). These 2 fields are an either/or – this is not quite made clear in the UI prompts, and is not enforced e.g. via a radio button choice or similar.

Once I did this I checked for updates in Webstorm, retried the new update, and it completed OK.

 

2/ Having done this, I restarted Webstorm and reloaded my Ionic project. Whilst loading the project, Kaspersky complained that “Server-side JavaScript run by a program with restrictions is attempting to create an embedded key or parameter in a protected registry key”

Effectively, Node.js was attempting to create a new subkey in the registry under TCP/IP Settings (not sure why it would do this, but I was confident that this was not Malware). Whilst Node.js was a trusted program, it was doing  it as instructed via an ionic batch script.

I tried to keep allowing the action but this did not work. The solution in the end came when I noticed that the component hierarchy mentioned in the Kaspersky error consisted of a series of green hyperlinks for each level. I was able to click on the green links, and this immediately took me to a Kaspersky settings screen for that component. I was able to see that the script component calling Node.js did not have permissions to create a security registry key. I was able to easily click on the relevant “?” entries to create a security registry subkey, and set the option to Yes.

So in all a plus for Kaspersky in making it easy to fix, but a minus as I had to work it out for myself and had not been able to find any online or other help on it.

Note for the future – any errors etc. from Kaspersky may have clickable links in them which take you to a place where you can add a rule to stop the error – this is always worth looking into. In my case the clickable links were not underlined but were green in colour.

Once I had done this, restarting Webstorm and opening the project went without any errors from Kaspersky.

No Comments »

April 26th, 2017
8:21 am
Ionic 2 Super Starter template application – Cannot find module "ionic-native"

Posted under Ionic
Tags , ,

This template is noteworthy as it contains a number of simple ready made use cases/patterns such as swipe gesture support, master/detail pages, searching, and simple entry forms.
As per this post, a tutorial starter app with the above template should be created as follows:-

ionic start my-super-starter-app super –v2
npm install

When I tried to run this I got the following error trace:-

Runtime Error

Cannot find module "ionic-native"

Stack

Error: Cannot find module "ionic-native"
at g (http://localhost:8100/build/polyfills.js:3:7133)
at Object.<anonymous> (http://localhost:8100/build/main.js:108352:7)
at __webpack_require__ (http://localhost:8100/build/main.js:20:30)
at Object.<anonymous> (http://localhost:8100/build/main.js:82204:73)
at __webpack_require__ (http://localhost:8100/build/main.js:20:30)
at Object.<anonymous> (http://localhost:8100/build/main.js:120594:70)
at __webpack_require__ (http://localhost:8100/build/main.js:20:30)
at http://localhost:8100/build/main.js:66:18 at http://localhost:8100/build/main.js:69:10

Ionic Framework: 3.0.1
Ionic Native: ^3.5.0
Ionic App Scripts: 1.3.0
Angular Core: 4.0.0
Angular Compiler CLI: 4.0.0
Node: 7.5.0
OS Platform: Windows 7
Navigator Platform: Win3
User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36

This Ionic forum post documents the problem, which appears to be because the starter template expects A version of ionic-native lower than 3 (mine was 3.5.0 as above). As per the post, I tried the following:-

  1. Edited my package.json and changed the ionic-native version to 2.9.0
  2. Entered npm install ionic-native –save

This did not work, it failed with a similar error.

Fortunately the post links to an updated template as the solution, in github here.

This can be cloned and used instead of entering ionic start my-super-starter-app super –v2

I tried the fixed version and it worked correctly. Note ref the comments in the various posts that it was not necessary to install ionic-native explicitly via npm install ionic-native –save

No Comments »

April 25th, 2017
6:52 pm
Ionic V2–starter app creation, folder structure, and menu toggle issues

Posted under Ionic
Tags , , ,

A new Ionic 2 application should be created via ionic-cli as follows:-

ionic start my-new-app tabs –v2

Note that the v2 switch is mandatory, as without it (and running ionic 2.2.1) I got a different folder structure which did not put the application code under a top level src/ directory – whilst this tutorial does not mention the switch, it is mentioned here.

Note also that the tabs keyword is an app template which creates a tabbed app. There are other choices as noted here .

The super starter template is noteworthy as it has simple examples of master/detail lists, searching, and simple forms. I tried this and had some issues getting it working but there is a fixed version which worked. I have documented this here.

Note also that this post here mentions using an earlier version of node (4.x) to avoid a number of issues. I have not tried that, as the current node version I have installed as I type is v7.5.0, which makes 4.x a pretty old version.

I may try the older one though, to see if the issues I hit with the menu toggle on the Nav bar menu might be solved. The issue I have hit is that the menu icon on the nav bar intermittently does not open the side menu. Typically clicking the same tab icon again or visiting another tab makes it work, such that it alternately fails and works. No solution has yet been found for this and I could not find any reference to it online.

Note that the default generated folder structure for —   v2 creates an app directory under /src, which is used for core app configuration stuff. I did attempt (mistakenly I now feel) putting the component and service layers under /src/app, but have now reverted that. Whilst this worked, when I then tried to move (with a webstorm refactor) /src/pages/ to /src/app/pages/ I hit numerous issues with  template errors/ html files not found when running ionic serve. I checked all the import and related configuration, and whilst some was incorrect, I eventually went through and corrected every .ts file individually and still had issues. This appears to be an issue – moving the /src/pages/ directory (for an app with the tabs template, as per the above ionic command) appears to break some hidden configuration that I could not find.

No Comments »

March 17th, 2017
12:36 pm
Ionic Styling issues with Menu button on an ion-navbar

Posted under Ionic
Tags , ,

When adding a menu button to an ion-navbar, there is a styling issue whereby the menu toggle gets the wrong styling.
This depends on whether the menuToggle attribute is present.

If the attribute is present and the toggle is placed inside an ion-buttons group, it gets the wrong styling via a special case for menu toggles (flex rather than inline-block like the rest). This (incorrectly) puts it on a separate line above the others. Putting it separately above the ion-buttons group, with an explicit left on the button, fixes the problem.

If the menuToggle attribute is NOT present, then the button needs to go inside the ion-buttons group as otherwise for example for a left group the other left buttons go to its left. The rules for all this styling seem a bit quirky and not clearly defined.

This post discusses this issue.

No Comments »

March 13th, 2017
3:27 pm
Using Sass Maps e.g. to get colors for custom components

Posted under Ionic
Tags

This is described in the theming docs here.

The above mentions using the color function to apply a color to an element.

The $colors defines a sass map of the color variants for Ionic. You can use the sass map-get() function to get colors from the map, as posted here:-

ion-menu ion-item span {       
 color: map-get($colors, primary);
}

However the correct way uses the color function as per the above theming docs and the comment in the above post:-

ion-menu ion-item span {
  color: color($colors, primary, base);
}

No Comments »