This blog post describes the migration of the Drag And Drop Calendar mobile app from Ionic 2 to Ionic 4.

 

This post is currently the somewhat raw notes that were taken during the migration. We will be adding to and updating this post as time permits, to make it easier to read and find information. But for now we wanted to get it "out there" so that hopefully others who are migrating from Ionic 2 or 3 to Ionic 4 can benefit.

 

Please leave a comment on this blog post if you have questions.

 

1. Ran “npm install -g ionic”, which replaced the ionic folder in Users\Mark\AppData\Roaming\npm\node_modules

 

2. Created blank ionic4 app with "ionic start c:\project\ionic\DragAndDropCalendar blank --type=angular", which ended with message “Your ionic app is ready to go”

 

3. Manually copied some files over from ionic2 to ionic folder following the example on the official Ionic 4 migration page, but not sure about some files such as ionic.ts, manifest.json, service-worker.js

 

4. Added angular.json file and src\tsconfig.app.json from copy from Ionic tabs sample app

 

5. Tried to run “ionic serve”, but prompted me to install @angular/cli, so clicked “yes” and got errors:

“You are running version v6.11.0 of Node.js, which is not supported by Angular CLI v6.

[ng] The official Node.js version that is supported is 8.9 and greater.

[ng] Please visit https://nodejs.org/en/ to find instructions on how to update Node.js.”

 

6. Downloaded node version 10.15.0 LTS msi and installed it

 

7. But then was getting “Cannot find module 'internal/util/types'” when trying any “npm install”

 

8. So changed npm, npm_cache, and nodejs folders to have “old” suffix, then removed and reinstalled node 10.15.0 LTS, then restarted VS Code, and finally got “npm install” to work

 

9 Ran “npm install -g ionic cordova” with following results:

“C:\Users\Mark\AppData\Roaming\npm\cordova -> C:\Users\Mark\AppData\Roaming\npm\node_modules\cordova\bin\cordova

C:\Users\Mark\AppData\Roaming\npm\ionic -> C:\Users\Mark\AppData\Roaming\npm\node_modules\ionic\bin\ionic

+ [email protected]

+ [email protected]

 

10. Ran “ionic serve” again, and received error, so ran “npm install @angular-devkit/build-angular” with following results:

“+ @angular-devkit/[email protected]

- then ran “ionic serve” again and got following error:

“Error: Missing binding C:\Project\ionic\DragAndDropCalendar\node_modules\node-sass\vendor\win32-x64-64\binding.node

[ng] Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 10.x

[ng] Found bindings for the following environments:

[ng]   - Windows 64-bit with Node.js 6.x

[ng] This usually happens because your environment has changed since running `npm install`.

[ng] Run `npm rebuild node-sass`”

 

11. Ran “npm rebuild node-sass”

 

12. Ran “ionic serve” again and got following error:

“ERROR in ./src/theme/variables.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/lib/loader.js??ref--14-3!./src/theme/variables.scss)

[ng] Module build failed (from ./node_modules/sass-loader/lib/loader.js):

[ng] undefined

[ng] ^

[ng]       File to import not found or unreadable: ionic.globals.

[ng]       in C:\Project\ionic\DragAndDropCalendar\src\theme\variables.scss (line 5, column 1)

[ng] ERROR in multi ./src/polyfills.ts ./node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/jit-polyfills.js

[ng] Module not found: Error: Can't resolve 'C:\Project\ionic\DragAndDropCalendar\src\polyfills.ts' in 'C:\Project\ionic\DragAndDropCalendar'

[ng] ERROR in The Angular Compiler requires TypeScript >=3.1.1 and <3.2.0 but 3.2.2 was found instead.”

 

13. Created file “src/polyfills.ts” and copied from the Ionic 4 sample app at the URL https://github.com/ionic-team/ionic-conference-app, and that error was resolved

 

14. Copied variables.scss code from a Side Menu starter app that I created with the Ionic 4 CLI

 

15. In package.json, changed typescript from “^3.2.2” to “~3.1.6”, based on version in Side Menu starter app and ionic sample app below, then ran “npm install typescript”, with following result:

“+ [email protected]

 

16. Ran “ionic serve” again, and received errors about @ionic/angular etc missing, and found that no longer had @ionic folder in node_modules

 

17. Reran “npm install @ionic/angular”, which added @ionic and @ionic-native folders under node_modules, and gave following result:

“+ @ionic/[email protected]

 

18. Reran “npm install @ionic/storage” with following result:

“+ @ionic/[email protected]

 

19. Reran “npm install rrule”, and “npm install @types/rrule” with following result:

“+ [email protected], + @types/[email protected]

 

20. Ggoogleplus setup: based on information at “https://www.npmjs.com/package/@ionic-native/google-plus”, ran “ionic cordova plugin add cordova-plugin-googleplus --variable REVERSED_CLIENT_ID=myreversedclientid”, which prompted me with “The config.xml file exists in project. Overwrite?”, so backed up existing contents of file and then clicked yes, and was prompted with “The resources/ directory exists in project. Overwrite?”, clicked No; the contents of config.xml was then wiped out, so pasted it back in, then ran the install again with following result:

“Adding cordova-plugin-googleplus to package.json

Saved plugin info for "cordova-plugin-googleplus" to config.xml”

 

21. Ran “npm install --save @ionic-native/google-plus” with following result:

“+ @ionic-native/[email protected]

 

22. Based on info in https://ionicframework.com/docs/native/google-plus/, changed the import statement and added constructor for GooglePlus, as shown below::

“import { GooglePlus } from '@ionic-native/google-plus/ngx';

constructor(private googlePlus: GooglePlus) { ...}”

 

23. Ran “npm install rxjs-compat --save”, which put entry for rxjs in package.json, and with following result:

“+ [email protected]

 

24. Ran “npm install intl”, with following result:

“+ [email protected]

 

25. Implemented necessary Ionic 4 markup changes from link below throughout app: replaced <ion-navbar> with <ion-toolbar>; <button ion-button> changed to <ion-button>; <ion-buttons end> changed to <ion-buttons slot=”end”>; added <ion-buttons slot=”start”><ion-back-button> to <ion-toolbar>; for <ion-grid> cols changed e.g. col-2 to size=”2”; added <ion-label> inside of <ion-item> when just displaying text; in <ion-item> changed e.g. item-left to slot=”start”; added <ion-label> inside of <ion-item-divider>; for <ion-label> changed stacked to position=”stacked”; added <ion-label> inside of <ion-list-header>; <ion-menu> changed e.g. (ionOpen) to (ionDidOpen); <ion-select> changed child elements from <ion-option> to <ion-select-option>; <ion-list radio-group> changed to <ion-list><ion-radio-group>; <ion-scroll> replaced with <ion-content>

https://github.com/ionic-team/ionic/blob/master/angular/BREAKING.md

 

26. Ran “ionic serve” again, and it's now ending in “Compiled Successfully”, with no errors, but still no html is being generated in the app, except for the index.html with the <app-root></app-root> tags; and fortunately main.js in Chrome is including some of my files, but unfortunately seems to be including everything, no lazy loading, i.e. App.Component, Home html and ts, Help, etc.

 

27. Side Menu starter app opens successfully when run “ionic serve”, so replaced the tsconfig.app.json file in Drag and Drop Calendar with Side Menu app’s version of the file

 

28. Found that my app has a bunch of errors in the Chrome console for references in index.html to main.css, cordova.js, and manifest.json, which are also not in Side Menu starter app’ss index.html, so commented them out

 

29. Only error left in Chrome console is use of global in index.js for “intl”, which is imported in calendar.module.ts, so commented out “import ‘intl’” lines, and error went away; however there are lines in polyfills.js above commented-out “import ‘intl’” lines that say “Date, currency, decimal and percent pipes. Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10”, but so far date pipes seem to work fine for Webview in mobile app

 

30. Now getting Chrome console error “Can't bind to 'loop' since it isn't a known property of 'ion-slides'.”; so temporarily removed attribute “[loop]="true"” from <ion-slides> elements; later changed to set loop = true in options in ts file instead of html, per links https://beta.ionicframework.com/docs/api/slides/ and

http://idangero.us/swiper/api/, and seems to work, at least no error in Chrome console; if hadn’t worked on device, maybe could have used “slides.startAutoplay” fix from aam-antonio in link below

https://github.com/ionic-team/ionic/issues/15242

 

31. Getting error in several html files that “Can't bind to 'ngFor' since it isn't a known property of 'th'”, so added import of CommonModule to calendar.module.ts and seems to have fixed it

 

32. Getting error in some views: “Can't bind to 'ngOutletContext' since it isn't a known property of 'template'.”, and per following link “ngOutletContext has been removed as it was deprecated since v4. Use ngTemplateOutletContext instead of ngOutletContext in angular 5”, so made that change throughout app

https://stackoverflow.com/questions/47221088/cant-bind-to-ngoutletcontext-since-it-isnt-a-known-property-of-ng-template

 

33. Getting error “Can't bind to 'content' since it isn't a known property of 'ion-menu'.”, so changed [content]=”content” to just content=”content”

 

34. Getting errors “Can't bind to 'ngModel' since it isn't a known property of 'ion-list'.” and “Can't bind to 'ngModel' since it isn't a known property of 'ion-checkbox'.”, so added imports of FormsModule from @angular/Forms to app.module.ts and home.module.ts

 

35. Getting error “NullInjectorError: No provider for GooglePlus!”, so added imports of GooglePlus  from @ionic-native/GooglePlus to app,module and home.module; but then getting error “Unexpected value 'GooglePlus' imported by the module 'AppModule'. Please add a @NgModule annotation.”

 

36. Per GooglePlus github Issue #519 and Ionic github issue #15135, ran “npm install --save @ionic-native/[email protected]”, and added “/ngx” to end of imports, with results below the links:

https://github.com/EddyVerbruggen/cordova-plugin-googleplus/issues/519

https://github.com/EddyVerbruggen/cordova-plugin-googleplus/issues/502

“+ @ionic-native/[email protected]

 

37. Still getting same errors, so tried just “npm install googleplus” without version, with following result:

“+ @ionic-native/[email protected]

 

38. Still got same errors, but also some warnings. So found links below, first link shows specific GooglePlus usage for Ionic Native, and second link below shows a general entry for Ionic Native plugins in module’s Providers section, instead of Imports section. So made the change to add GooglePlus to providers, and got past the error, and now successfully showing side menu, and also grid layout on a page for the first time, including correct dates on the day cells

https://beta.ionicframework.com/docs/native/google-plus

https://beta.ionicframework.com/docs/native/#Add_Plugins_to_Your_App_Module

 

39. Now getting the error talked about in GooglePlus github issue #519 “Object(...) is not a function”, and found that I had version 5.1.1 of the plugin installed which is from 2016, so did a npm remove, then “ionic cordova plugin add [email protected] --variable REVERSED_CLIENT_ID=myreversedclientid”, but same error, maybe just due to not being on a device?

 

40. Also getting several errors “Converting circular structure to JSON”, one of which involves Zones

 

41. Ran “ionic cordova platform add android”, received “Android project created with [email protected]” and “Saving android@~7.1.4 into config.xml file”

 

42. Realized cordova plugin version are all the same as in ionic2 version of the app, i.e. they didn’t get updated for Ionic 4, so as with GooglePlus above, updated to beta versions of ionic native and latest plugin using the following commands, and their associated results in quotes below the commands:

ionic cordova plugin add [email protected]

npm install --save @ionic-native/status-bar@beta

“+ @ionic-native/[email protected]

ionic cordova plugin add [email protected]

npm install --save @ionic-native/splash-screen@beta

“+ @ionic-native/[email protected]

ionic cordova plugin add cordova.plugins.diagnostic

npm install --save @ionic-native/diagnostic@beta

“+ @ionic-native/[email protected]

ionic cordova plugin add [email protected]

npm install --save @ionic-native/[email protected]

“+ @ionic-native/[email protected]

(originally installed the default beta.ss, but was getting error in Issue 2642, said to revert to beta15)

ionic cordova plugin add [email protected]

npm install --save @ionic-native/device@beta

“+ @ionic-native/[email protected]

 

43. Added “/ngx” to end of import statements for each ionic native plugin above, in all components

 

44. Ran “ionic cordova run android --verbose”, got error “Error: Could not find module "@ionic/ng-toolkit"”, link below said to replace @ionic/ng-toolkit and @ionic/schematics-angular with @ionic/angular-toolkit in angular.json, which corresponded with the angular.json file in the Side Menu starter app; but then got error “Could not find module "@ionic/angular-toolkit"”, and found that @ionic/angular-toolkit was missing from node_modules but exists in Side Menu starter app, so ran “npm install @ionic/angular-toolkit”, with result:

“+ @ionic/[email protected]

https://github.com/ionic-team/ionic-cli/issues/3763

 

45. Ran “ionic cordova run android --verbose” again, and made more progress including following responses:

“Preparing "Install Android SDK Platform 27 (revision: 3)"”

"Install Android SDK Platform 27 (revision: 3)" ready.

Installing Android SDK Platform 27 in C:\Users\Mark\AppData\Local\Android\sdk\platforms\android-27

"Install Android SDK Platform 27 (revision: 3)" complete.

"Install Android SDK Platform 27 (revision: 3)" finished.

...

“BUILD SUCCESSFUL”

Built the following apk(s):

C:\Project\ionic\DragAndDropCalendar\platforms\android\app\build\outputs\apk\debug\app-debug.apk

“LAUNCH SUCCESS”

“Failed to load resource...net::ERR_FILE_NOT_FOUND file:///runtime.js, polyfills.js, styles.js, cordova.js, vendor.js, main.js, assets/icon/favicon.ico”

 

46. App seems to have installed on phone, but just getting blank white screen

 

47. Ran npm steps below per the following Ionic CLI issue from 12/2018:

https://github.com/ionic-team/ionic-cli/issues/3530

a. npm uninstall -g cordova

b. npm install -g cordova (result: “+ [email protected]”, which was the result of “cordova -v” before rm)
c. ionic cordova platform remove android
d. ionic cordova platform add android (“Android target: android-27...Android project created with [email protected])
e. npm i cordova-plugin-ionic-webview@^2.1.3 (+ [email protected])
f. cordova plugin rm cordova-plugin-ionic-webview (“Plugin "cordova-plugin-ionic-webview" is not present in the project”)
g. cordova plugin add cordova-plugin-ionic-webview (“Installing "cordova-plugin-ionic-webview" for android”)

 

48. The app loaded on my device, with a grid showing dates and day names, and top menu and side menu

 

49. Still not getting a prompt to login to Google, and so the grid has no calendar events, and swiping works a little in each direction and only shows Xmas week and week of 1/6/2018 thru 1/13/2018 and following week, with wrong week description sometimes on the top menu, and Add Event button doesn’t work, and radio buttons for calendar mode don’t have grouping, and Settings button doesn’t work

 

50. Add Event button fires the event handler in home.page.ts, but when gets calendarList from storage, it’s null, so doesn’t load the page, probably due to next set of errors below

 

51. Getting error below, so removed all references to HomePage in app.component.ts, app.component.html, and app.module.ts, and that got rid of the error, and app load hit my breakpoint in app.component.ts constructor

stack:"Error: Uncaught (in promise): Error: Type HomePage is part of the declarations of 2 modules: AppModule and HomeModule! Please consider moving HomePage to a higher module that imports AppModule and HomeModule. You can also create a new NgModule that exports and includes HomePage then import that NgModule in AppModule and HomeModule.”

 

52. Now getting error “Error: Uncaught (in promise): Error: Template parse errors:\nCan't bind to 'eventSource' since it isn't a known property of 'calendar'.”, and same error for calendarDate and calendarMode, i.e. all properties of <calendar> element in Home.page.html, so seems like CalendarComponent from calendar.ts is not getting imported, even though calendar.module.ts imports it and includes it in its Declarations and imports and entryComponents, so tried adding CalendarComponent to providers, but same error; turned out the fix was to add an import to home.module.ts for the export class from calendar.module.ts, "NgCalendarModule"

 

53. Getting error below for ion-datetime, fixed the error by importing CommonModule from @angular/common in home.module

stack:"Error: Uncaught (in promise): Error: Template parse errors:\nCan't bind to 'ngIf' since it isn't a known property of 'ion-datetime'.\n1. If 'ion-datetime' is an Angular component and it has 'ngIf' input, then verify that it is part of this module.\n2. If 'ion-datetime' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.\n3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

 

54. Getting error below, fixed by removing NavParams from Home, Settings, etc.:

stack:"Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[HomePage -> NavParams]: \n  StaticInjectorError(Platform: core)[HomePage -> NavParams]: \n NullInjectorError: No provider for NavParams!

 

55. Getting error below; so seems like it’s stepping into Add Event, but can’t set a breakpoint, says undefined breakpoint, maybe due to lazy loading? Try adding “debugger;” line to Add Event code per first link below

https://stackoverflow.com/questions/46163465/debug-lazy-loaded-angular-2-module-in-chrome-vs-code

https://medium.com/front-end-weekly/a-guide-to-debugging-angular-applications-5a36bd88b4cf

Stack:"Error: Uncaught (in promise): TypeError: Cannot read property 'setSeconds' of undefined\nTypeError: Cannot read property 'setSeconds' of undefined\n    at new AddEvent (http://localhost:8080/add-event-add-event-module.js:221:49)\n

 

56. Getting error below, which was fixed by removing [disabled]="isToday" from Today button

stack:"Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'disabled: undefined'. Current value: 'disabled: true'.\n    at viewDebugError (http://localhost:8080/vendor.js:52393:15)\n at expressionChangedAfterItHasBeenCheckedError

 

57. Also getting below Object error on GooglePlus, assuming because it’s now trying to call the Google Plus code, fixed error by running “npm install @ionic-native/core@beta”, and it updated from 4.18 to 5.0 beta with following result:

“+ @ionic-native/[email protected]

stack:"Error: Uncaught (in promise): TypeError: Object(...) is not a function\nTypeError: Object(...) is not a function\n    at GooglePlus.push../node_modules/@ionic-native/google-plus/ngx/index.js.GooglePlus.trySilentLogin (http://localhost:8080/vendor.js:75534:137)\n    at HomePage.push../src/app/home/home.page.ts.HomePage.login

 

58. Added line “debugger;” at top of home.ts  and app.component.ts, now consistently stops at breakpoints when first starting the app

 

59. Getting error when start the app “Application Error - The connection to the server was unsuccessful. (file:///android_asset/www/index.html)”,  tried to comment out links to google api’s and icon.png in index.html but didn’t work, finally “solved” by adding line “<preference name="loadUrlTimeoutValue" value="700000" />” to config.xml per following link

https://stackoverflow.com/questions/12319809/application-error-the-connection-to-the-server-was-unsuccessful-file-andr

 

60. Changed Home page to pass eventSource and calendarList to Add Event and Edit Event using new AddEditEventParams service per following link:

https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/

 

61. When calling Google API in getGoogleAccessToken, getting error below, after investigations described below, reallized that the origin in the error below has port 8080, and that the only Approved Javascript Origin I had configured on console.developers.google.com for Web Client 1 for the Ionic2 version of the app was for port 8000, so added a new allowed origin for 8080, still didn’t work; so tried to change from application/x-www-form-urlencoded to application/json, but then got extra error message in the error below:Response to preflight request doesn't pass access control check”); so removed withCredentials: true, which finally worked, we're now getting events on the Week Agenda view for the first time

Access to XMLHttpRequest at 'https://www.googleapis.com/oauth2/v4/token' from origin 'http://localhost:8080' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. [http://localhost:8080/home]

 

62. Maybe could also have used Angular's new HttpClient instead of older Http for requests to the Google API, or replaced http.post with gapi.client.request, which I’m already using for calls to calendar API, in both getGoogleAccessToken and getGoogleAccessTokenUsingRefreshToken; or try changing from Headers to HttpHeaders for Angular 5+; not sure if there was a change to http.post in angular 5+?:  per following link, “Using the Maps JavaScript API that way—by way of a script element to load the library, and then using the google.maps.Map and other google.maps.* methods—is the only supported way. Google intentionally does not allow doing it by way of requests sent with XHR or the Fetch API.”

https://stackoverflow.com/questions/43443836/cors-and-google-maps-http-api-calls?noredirect=1&lq=1

 

64. For Lazy Loading, added module.ts file for home, help, and settings pages, and instead of recommended approach of adding app-routing.module.ts file, currently just using the simpler option to include the routes in app.module.ts. with router section as shown in Create Your Routes section of https://www.joshmorony.com/my-method-for-upgrading-from-ionic-3-to-ionic-4/, and similar to example in LazyLoading section of  

https://www.joshmorony.com/using-angular-routing-with-ionic-4/

 

65. When WeekAgendaView loads, getting errors “The "panend" event cannot be bound because Hammer.JS is not loaded and no custom loader has been specified.”, also for events tap, press, panstart, panmove; ran “npm install --save hammerjs” (result of “+ [email protected]”),  and added “import 'hammerjs'” to main.ts, which got rid of errors and successfully able to drag and drop on WeekAgendaView ; changes were based on following link which talks about npm installing hammerjs and also using @angular/platform-browser with it, and at the end talks about customizing the directions that the events handle, e.g. maybe can customize pan to only trigger when panning vertically, so doesn’t interfere with horizontal swiping for the slider

 

https://blog.angularindepth.com/gestures-in-an-angular-application-dde71804c0d0

 

66. Edit Event - error when clicking on Event Repeats checkbox when div below it is closed, and also same error on initial load of the app; fixed by moving [(ngModel)] out of all <ion-list> elements, and onto their child form elements, e.g. <ion-radio-group>

stack:"Error: No value accessor for form control with unspecified name attribute\n    at _throwError (http://localhost:8080/vendor.js:58755:11)\n at setUpControl (http://localhost:8080/vendor.js:58665:9)\n    at NgModel.push../node_modules/@angular/forms/fesm5/forms.js.NgModel._setUpStandalone (http://localhost:8080/vendor.js:61393:9)\n    at NgModel.push../node_modules/@angular/forms/fesm5/forms.js.NgModel._setUpControl (http://localhost:8080/vendor.js:61380:37)\n at NgModel.push../node_modules/@angular/forms/fesm5/forms.js.NgModel.ngOnChanges

https://stackoverflow.com/questions/50433571/no-value-accessor-for-form-control-with-unspecified-name-attribute-in-angular-5

https://stackoverflow.com/questions/38958347/angular2-rc-5-custom-input-no-value-accessor-for-form-control-with-unspecified

 

67. Settings and Help pages - not navigating to pages when click menu items, although no errors are appearing, tried changing from click handler with router called in ts code, to routerDirection and routerLink params in app.component.page markup, and also tried commenting out menu item’s onDidClose and Open handlers, and still no luck; wound up being fixed by changing the help and settings modules to use the “component” property in the route definition