<aside> ⚠️ The guide is written to upgrade:

Starting from earlier versions might work, but it’s not guaranteed (it will probably need extra work). Read more in the previous upgrade guide.

</aside>

<aside> 🎏 References:

Step by step guide

<aside> 🆚 Before to start, make sure your developer tools are updated to the versions stated in our Development basics guide.

</aside>

<aside> ⚠️ Note: Angular has a new default builder, but for now we stick with the old one, because the changes in the codebases would be too big; we will monitor the situation in the next few releases.

</aside>

<aside> 💁 NOT within this update, but soon we will start using Angular’s Signals more often, to switch from zone-based apps to the newer standards. If you want, you can start practice from now on with simple pages.

</aside>

Front-end

  1. Locate the front-end folder.

  2. In the package.json file remove any @idea-ionic/xxx package. Then, run npm i.

  3. Run ng update --allow-dirty @angular/core@18 @angular/cli@18 which should bring you to version 18 of Angular.

    <aside> 🤖 If the operation throws errors on incompatible packages, remove them temporarily from the package.json You will re-add them after the update to Angular 18 is completed.

    </aside>

  4. Remove the package-lock.json file and the node_modules folder.

  5. In the package.json file, refer to to the following versions for dependencies and devDependencies and manually fix the packages versions so that all of IDEA’s projects are aligned to the very same state. Note: you don’t have to add packages that your codebase don’t need; also: there could be some packages missing from the list.

  6. Substitute the following files’ content:

  7. For projects using @idea-ionic/barcode, you must switch to @capacitor-mlkit/barcode-scanning from @capacitor-community/barcode-scanner (use this PR as the guideline to make the changes: https://github.com/iter-idea/iiwms/pull/643).

    <aside> ⚠️ Note that some files update automatically after npx cap sync. Don’t edit them manually.

    </aside>

  8. Run a npm i to reinstall everything from a clean state.

  9. If the app is deployed on either iOS or Android, upgrade Capacitor to v6 by running npx cap migrate; no manual changes should be necessary, but in case of issues refer to the official guide linked at the top of this manual.

    <aside> 💬 In case of weird warnings/errors out of the scope of the official guide, contact @Matteo Carbone.

    </aside>

  10. From the front-end folder, run npm i PACKAGE@latest, for each of the following packages:

    <aside> ⚠️ When updating these libraries, check the release notes from the previous version to make according changes. For IDEA Ionic Extra, also remember to update the i18n dictionaries.

    </aside>

    1. idea-toolbox.
    2. All the @idea-ionic/xxx and other packages removed in the first steps.
    3. Consider also installing the latest version of the @capacitor-community/… plugins.
  11. From the front-end folder, remove again the package-lock.json file and node_modules folder. Then run npm i: at this point, it shouldn’t throw any errors or vulnerability.

  12. Adapt the source code to Ionic’s latest changes (and IDEA’s latest standards), by following the official migration guide and the specifications below.

    1. Fix CSS, theme and colours:

      • Remove colours if they don’t change the default values.
      • Change the positioning of the dark mode values (in :root).
      • Fix step-colours naming.
      • Remove dynamic font instruction.

      <aside> 💁 Suggestions:

      • Example of a new global.scss file.
      • Example of a new theme/variables.scss file. </aside>
    2. Labels: migrate any remaining instances of the following components to use the modern form control syntax:

      • Input;
      • Textarea;
      • Select;
      • Radio;
      • Checkbox;
      • Toggle.
      <!-- before -->
      <ion-label position="stacked">{{ 'MYSTR' | translate }}</ion-label>
      <ion-input />
      
      <!-- after -->
      <ion-input labelPlacement="stacked" [label]="'MYSTR' | translate" />
      
      <!-- special case for checkbox, toggle -->
      <ion-checkbox labelPlacement="stacked">{{ 'MYSTR' | translate }}</ion-checkbox>
      

      <aside> 💁 Suggestion: search <ion-label in VSC to find most of the occurrences.

      </aside>

      <aside> ⚠️ Exceptional case: obligatoryDot and other more complex structures for ion-label; note: if a similar result can be achieved with the standard way described above, it’s preferable.

      <!-- before -->
      <ion-label position="stacked">
        {{ 'MYSTR' | translate }} <ion-text class="obligatoryDot" />
      </ion-label>
      <ion-input />
      
      <!-- after -->
      <ion-input labelPlacement="stacked">
        <div slot="label">
          {{ 'MYSTR' | translate }} <ion-text class="obligatoryDot" />
        </div>
      </ion-input>
      

      </aside>

    3. Fix occurrences of counter, slot="error", slot="helper".

    4. Check if any [innerHtml] attributes. They are now hidden by default and must be sanitised before passing them to the components. Check how here. NOTE: If the page is not loading, try passing the innerHtml contents to a div or span.

    5. In the global stylesheet (and everywhere they are used), fix the behaviour of the highlight colours (from ion-item to ion-input, ion-textarea, ion-select).

      /* before */
      ion-item {
        --highlight-color-focused: var(--ion-color-primary);
        --highlight-color-valid: var(--ion-color-primary);
        --highlight-color-invalid: var(--ion-color-primary);
      }  
      
      /* after */
      ion-input,
      ion-textarea,
      ion-select {
        --highlight-color-focused: var(--ion-color-primary);
        --highlight-color-valid: var(--ion-color-primary);
        --highlight-color-invalid: var(--ion-color-primary);
      }
      
    6. Refactor self-closing tags (e.g. ion-input, ion-icon, o idea-*something*).

      <!-- before -->
      <ion-input></ion-input>
      
      <!-- after -->
      <ion-input />
      

      <aside> 💁 Suggestion: search ></ and > </ in VSC to find most of the occurrences.

      </aside>

      <aside> ⚠️ Exceptions, i.e. not self-closing, even if empty: div, ng-content, canvas, p, span.

      </aside>

    7. Change the coding style of Angular services.

      // before
      constructor(private modalCtrl: IDEALoadingService) { /* ... */ }
      
      // after
      private _modal = inject(IDEALoadingService)
      

      <aside> ⛔ IT IS FORBIDDEN to use the massive search/replace of VSC because it leads to unwanted substitutions and consequent errors. Use instead the “rename symbol” option of VSC.

      </aside>

      <aside> 💁 The translations service new naming is _translate (previously: t). Also, make sure that the template doesn’t use it (use | translate instead).

      </aside>

    8. Refactor the code to use the new Angular syntax for flow control: *ngIf, *ngFor, etc. → @if, @for, etc. This leads to an improvement in performance “for free”.

      <aside> 💁 Suggested procedure.

      1. Install in the front-end folder of the project the latest version of Prettier (devDependencies).

      2. Edit the file .prettierrc adding the following line at the bottom:

        "overrides": [{ "files": "front-end/**/*.html", "options": { "parser": "angular" } }]
        
      3. Close Visual Studio Code completely and re-open it.

      4. From the front-end folder, run the command (confirm the default options):

        ng generate @angular/core:control-flow
        
      5. After the automatic refactoring is completed, from Source Control (Git), open each file and:

        1. Save it — to apply Prettier’s formatting to the template; note: if the previous points succeeded, the new control flow syntax should be correctly indented inside the template.
        2. Search for any occurrence of methods “trackBy” and replace it with template code.
        3. Fix every “track” (@for) to use the correct attribute: id, object or $index.
        4. Use $index, $odd, etc. directly, instead of re-defining them in the for syntax.
        5. Check every changed file (with particular attention to complex flows) for the correctness of the generation; I’ve found a few cases where the generation was not correct. </aside>