Quantcast
Channel: Ionic Framework - Ionic Forum
Viewing all 49385 articles
Browse latest View live

Ion-input, autocapitalize not working on Ionic v8

$
0
0

Just test with stackblitz

  <ion-item>
    <ion-input
      label="Input with value"
      value="121 S Pinckney St #300"
      [autocapitalize]="true"
    ></ion-input>
  </ion-item>

autocapitalize is not working now. any comments?

1 post - 1 participant

Read full topic


Opening another app(files app) in a modal in ionic

$
0
0

i need a way to open an app(files app) in a modal in ionic similar to how WhatsApp does it, it makes the app more accessible to users with low end androids.

5 posts - 2 participants

Read full topic

Angular development server with Ionic is extremely slow

$
0
0

Any idea why angular development server with ionic is responding extremely slow?
I used to work with Angular+Capacitor and i have never had issue like this.

It’s frustrating to me to wait 30 seconds to refresh after every change in code.

2 posts - 2 participants

Read full topic

In my angular ionic framework to connect sqlite but jeep-sqlite not present in dom error showing

$
0
0

in my angular ionic framework to connect sqlite but jeep-sqlite not present in dom error showing il and share your code, configuration, and other relevant info.

2 posts - 2 participants

Read full topic

Issues on iOS 18.5 – Custom Swiper Misbehaving & App Lagging

$
0
0

Hi Ionic Team and Community,

We are experiencing a critical issue after our customer upgraded to iOS 18.5.

Problem Description:

  • Our app contains a custom swiper component, which is used in a loop to display time slots.
  • Previously, swiping on a specific time slot would select and act on that slot.
  • However, after the iOS 18.5 update, swiping on the first time slot incorrectly selects the second slot instead. The swipe behavior is now misaligned.
  • This was not an issue on earlier iOS versions (including 18.4.x and below).
  • In addition to the swiper bug, the app overall feels laggy and unresponsive, occasionally hanging during user interaction.

Technical Context:

  • Framework: Ionic 6 / Angular
  • Swiper: Custom-built swiper logic (not using Swiper.js or external lib)
  • Affected Device(s): iPhones and iPads running iOS 18.5
  • Unchanged Code: No code changes have been made recently; this issue surfaced immediately after the iOS upgrade.

Request:

  • Has anyone else in the community faced similar issues on iOS 18.5?
  • Are there known compatibility issues or updates required for hybrid apps with the iOS 18.5 release?
  • Any recommended workarounds for swipe handling or performance tuning?

Any help or insight would be greatly appreciated.

Thanks in advance!
Kaushal

1 post - 1 participant

Read full topic

Connect Sqlite and create a table

$
0
0

Continuing the discussion from In my angular ionic framework to connect sqlite but jeep-sqlite not present in dom error showing:

my sqlite service

import { Injectable } from ‘@angular/core’;
import { Capacitor } from ‘@capacitor/core’;
import { CapacitorSQLite, SQLiteConnection, SQLiteDBConnection } from ‘@capacitor-community/sqlite’;

@Injectable({
providedIn: ‘root’
})
export class SqliteService {
private sqlite: SQLiteConnection;
private db: SQLiteDBConnection | null = null;

constructor() {
this.sqlite = new SQLiteConnection(CapacitorSQLite);
}

async init() {
try {
console.log(‘Checking CapacitorSQLite…’);
console.log(‘CapacitorSQLite:’, CapacitorSQLite);
console.log(‘Checking IndexedDB support:’, !!window.indexedDB);

if (Capacitor.getPlatform() === 'web') {
  console.log('Running on web, initializing web store...');
  try {
    console.log("tryblock")
   await this.sqlite.initWebStore();
    console.log('Web store initialized successfully');
  } catch (webInitErr) {
    console.error('Error during initWebStore:', webInitErr);
  }
}

console.log(‘Before creating connection…’);

this.db = await this.sqlite.createConnection('testdb', false, 'no-encryption', 1, false);
const isOpen = await this.db.isDBOpen();

console.log(‘DB is open?’, isOpen);

await this.db.open();
console.log(' creating connection...');

console.log('DB connection opened');

await this.db.execute(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT
  )
`);
console.log('Table created or exists');

} catch (err) {
console.error(‘SQLite init error:’, err);
}
}

async addUser(name: string) {
if (!this.db) {
console.error(‘DB not initialized’);
return;
}
const stmt = INSERT INTO users (name) VALUES (?);
const result = await this.db.run(stmt, [name]);
console.log(‘Insert Result:’, result);
}

async getUsers() {
if (!this.db) return ;
const result = await this.db.query(‘SELECT * FROM users’);
return result.values ?? ;
}
}
appcomponent.ts

import { Component } from ‘@angular/core’;
import { Platform } from ‘@ionic/angular’;
import { SqliteService } from ‘./services/sqlite.service’;

@Component({
selector: ‘app-root’,
templateUrl: ‘app.component.html’,
styleUrls: [‘app.component.scss’],
standalone: false,
})
export class AppComponent {
constructor(private platform: Platform, private sqliteService: SqliteService) {
this.platform.ready().then(async () => {
console.log(‘Platform is ready!’);
await this.sqliteService.init();
console.log(‘SQLite service initialized!’);
await this.addUser();
});
}
async addUser() {
await this.sqliteService.addUser(‘John’);
const users = await this.sqliteService.getUsers();
console.log(users);
}
}
main.ts

import { platformBrowserDynamic } from ‘@angular/platform-browser-dynamic’;
import { AppModule } from ‘./app/app.module’;

platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
connect sqlite time jeep-sqlite not present in Dom message showing table not created

2 posts - 2 participants

Read full topic

Executing necessary code when App is started in the background by iOS for location changes (Ionic/Angular)

$
0
0

Hi,

My Ionic Angular App enables location tracking and location changes are saved in Firebase. With location permission set to Always, if the App is closed, iOS starts the App in the background when a location changes by a certain distance. However when the App is started in the background by iOS I have found that the normal path of starting the App, through AppComponent code, is not executed and my Firebase connection is not setup (as it would in a normal foreground startup) to save the new location there.

So my questions are -

  1. Is this the expected behavior that the App started by iOS in background won’t execute the AppComponent code
  2. When the App starts in the background how do I execute the needed code to setup my Firebase connection and save the changed location there.
  3. What code is executed when the App is started in the background by iOS when triggered by location change?

I am on Ionic and Capacitor version 7.

Thank you for your guidance.

Sanjay.

1 post - 1 participant

Read full topic

Ion-popover opens in a non-optimal direction

$
0
0

When I click a button, a popover is shown. “side” is set at its default value (“bottom”), so, by default, the popover appears under the clicked button.

When there’s little space under the button, the popover appears on top of the button instead, which is smart because it has more space to grow in that direction. The problem is, sometimes that doesn’t seem to work and the popup appears under the button anyways, which makes it unreadable.

In the images (below), I scrolled the button (yellow) to 4 different positions and then clicked it. You can see the results of the popover. The first and second images (especially the second one) are sub-optimal, as the popover already has way more growth space on top of the button.

In a minimal sample project, the issue seems to be less noticeable.

My questions are the following:

  1. Can someone please explain how does the popover pick which side to grow? That may help me to understand why this issue is so noticeable in my project.
  2. Does anyone know if it’s possible to tell the popover to always appear centered in the screen? I may simply do that as a workaround.

Thanks!

1 post - 1 participant

Read full topic


Kamal Hinduja Geneva, Switzerland- how to Test API Under Different condition?

$
0
0

Hi All,

I’m Kamal Hinduja from Geneva, Switzerland. I have create an API for Project. Can anybody share what are API testing and what are the tool that used for API Testing. Please share step by step procedure for API Testing.

Thanks, Regards
Kamal Hinduja Geneva, Switzerland

1 post - 1 participant

Read full topic

HTMLIonSelectElement.setFocus Error in VS Code: Property 'setFocus' does not exist on type 'HTMLIonSelectElement'.ts(2339), but works at run time

$
0
0

Ionic 8.5, TypeScript 4.9.5, VSCode 1.98.2.

ionSelectRef.current.setFocus() shows error in VS code as below, but it works just fine, in Web Browser, Android, and iOS, it does scroll the page the where the select item is, even though the cursor does not show, which I think is normal as it is not a keyboard input field.

Property ‘setFocus’ does not exist on type ‘HTMLIonSelectElement | HTMLIonInputElement | HTMLIonRadioGroupElement | HTMLIonTextareaElement | HTMLIonCheckboxElement’.
Property ‘setFocus’ does not exist on type ‘HTMLIonSelectElement’.ts(2339)

1 post - 1 participant

Read full topic

Push notifications, ionic capacitor 5

$
0
0

This is my code for initializing push notifications, when i open the apk the app automatically closes, can someone point out what am i missing here

import { Injectable } from '@angular/core';
import { Capacitor } from '@capacitor/core';
import { ActionPerformed, PushNotifications, PushNotificationSchema, Token } from '@capacitor/push-notifications';
import { ModalController } from '@ionic/angular';
import { BehaviorSubject } from 'rxjs';
import { NotificationPage } from '../notification/notification.page';
// import { Plugins } from '@capacitor/core';
import { App } from '@capacitor/app';
import { registerPlugin } from '@capacitor/core';

// const { AppSettingsOpener } = Plugins;
export interface AppSettingsOpenerPlugin {
  open(): Promise<void>; // Declare the method signature
}
export const AppSettingsOpener = registerPlugin<AppSettingsOpenerPlugin>('AppSettingsOpener');

export const FCM_TOKEN = 'push_notification_token';

@Injectable({
  providedIn: 'root'
})
export class FcmService {

  private _redirect = new BehaviorSubject<any>(null);

  get redirect() {
    return this._redirect.asObservable();
  }

  constructor(public modalCtrl: ModalController,

  ) { }

  initPush() {
    if (Capacitor.getPlatform() !== 'web') {
      this.registerPush();
      // this.getDeliveredNotifications();
      App.addListener('appStateChange', async ({ isActive }) => {
        if (isActive) {
          console.log('App is active again. Retrying permission check...');
          this.registerPush(); // retry registering and requesting permission
        }
      });
    }
  }

  // private async registerPush() {
  //   try {
  //     await this.addListeners();
  //     let permStatus = await PushNotifications.checkPermissions();

  //     if (permStatus.receive === 'prompt') {
  //       permStatus = await PushNotifications.requestPermissions();
  //     }

  //     if (permStatus.receive !== 'granted') {
  //       throw new Error('User denied permissions!');
  //     }

  //     await PushNotifications.register();
  //   } catch(e) {
  //     console.log(e);
  //   }
  // }
  private async registerPush() {
    try {
      await this.addListeners();

      const granted = await this.ensurePushPermission();
      if (!granted) {
        console.warn('Notification permission not granted by user');
        return;
      }

      await PushNotifications.register();
    } catch (e) {
      console.error('Push registration failed:', e);
    }
  }
  private async ensurePushPermission(): Promise<boolean> {
    let permStatus = await PushNotifications.checkPermissions();
    console.log('Permission status (before):', permStatus);

    if (permStatus.receive === 'prompt') {
      permStatus = await PushNotifications.requestPermissions();
      console.log('Permission status (after prompt):', permStatus);
    }

    if (permStatus.receive !== 'granted') {
      console.warn('User denied notification permissions.');
      const confirmed = confirm('This app needs notification permission. Would you like to open settings to enable it?');
      if (confirmed) {
        try {
          await AppSettingsOpener.open();

        } catch (e) {
          console.error('Failed to open settings:', e);
        }
      }
      return false;
    }

    return true;
  }

  async getDeliveredNotifications() {
    const notificationList = await PushNotifications.getDeliveredNotifications();
    console.log('delivered notifications', notificationList);
  }

  addListeners() {
    PushNotifications.addListener(
      'registration',
      async (token: Token) => {
        console.log('My token: ', token);
        const fcm_token = (token?.value);
        let go = 1;
        const saved_token = JSON.parse((await localStorage.getItem('pushtoken')));
        if (saved_token) {
          if (fcm_token == saved_token) {
            console.log('same token');
            go = 0;
          } else {
            go = 2;
          }
        }
        if (go == 1) {
          // save token
          localStorage.setItem('pushtoken', JSON.stringify(fcm_token));
        } else if (go == 2) {
          // update token
          const data = {
            expired_token: saved_token,
            refreshed_token: fcm_token
          };
          localStorage.setItem('pushtoken', fcm_token);
        }
      }
    );

    PushNotifications.addListener('registrationError', (error: any) => {
      console.log('Error: ' + JSON.stringify(error));
    });

    PushNotifications.addListener(
      'pushNotificationReceived',
      async (notification: PushNotificationSchema) => {
        console.log('Push received: ' + JSON.stringify(notification));
        const data = notification?.data;
        if (data?.redirect) this._redirect.next(data?.redirect);
      }
    );

    PushNotifications.addListener(
      'pushNotificationActionPerformed',
      async (notification: ActionPerformed) => {
        const data = notification.notification.data;
        setTimeout(() => {
          this.shownotifications();
        }, 1000);
        console.log('Action performed: ' + JSON.stringify(notification.notification));
        console.log('push data: ', data);
        if (data?.redirect) this._redirect.next(data?.redirect);
      }
    );
  }
  async shownotifications() {
    const modal = await this.modalCtrl.create({
      component: NotificationPage,
      animated: true,
      // mode: 'ios',
      backdropDismiss: true,
    })

    return await modal.present();
  }

  async removeFcmToken() {
    try {
      const saved_token = JSON.parse((await localStorage.getItem('FCM_TOKEN')));
      localStorage.removeItem('FCM_TOKEN');
    } catch (e) {
      console.log(e);
      throw (e);
    }

  }
}```

This is my package.json

{
“name”: “appname”,
“version”: “0.0.1”,
“author”: “Ionic Framework”,
“homepage”: “https://ionicframework.com/”,
“scripts”: {
“ng”: “ng”,
“start”: “ng serve”,
“build”: “ng build”,
“test”: “ng test”,
“lint”: “ng lint”,
“e2e”: “ng e2e”
},
“private”: true,
“dependencies”: {
@angular/common”: “~13.2.2”,
@angular/core”: “~13.2.2”,
@angular/forms”: “~13.2.2”,
@angular/platform-browser”: “~13.2.2”,
@angular/platform-browser-dynamic”: “~13.2.2”,
@angular/router”: “~13.2.2”,
@awesome-cordova-plugins/android-permissions”: “^6.13.0”,
@awesome-cordova-plugins/app-version”: “^5.44.0”,
@awesome-cordova-plugins/background-mode”: “^5.43.0”,
@awesome-cordova-plugins/camera”: “^5.44.0”,
@awesome-cordova-plugins/camera-preview”: “^5.44.0”,
@awesome-cordova-plugins/chooser”: “^5.43.0”,
@awesome-cordova-plugins/core”: “^5.46.0”,
@awesome-cordova-plugins/device”: “^5.44.0”,
@awesome-cordova-plugins/document-scanner”: “^5.43.0”,
@awesome-cordova-plugins/file”: “^6.13.0”,
@awesome-cordova-plugins/file-opener”: “^5.44.0”,
@awesome-cordova-plugins/file-path”: “^5.44.0”,
@awesome-cordova-plugins/file-transfer”: “^5.44.0”,
@awesome-cordova-plugins/in-app-browser”: “^5.45.0”,
@awesome-cordova-plugins/multiple-document-picker”: “^5.44.0”,
@byteowls/capacitor-oauth2”: “^4.0.2”,
@capacitor-community/speech-recognition”: “^6.0.0”,
@capacitor/android”: “5.7.6”,
@capacitor/app”: “^5.0.0”,
@capacitor/core”: “^5.7.6”,
@capacitor/filesystem”: “^6.0.2”,
@capacitor/haptics”: “^5.0.0”,
@capacitor/keyboard”: “^5.0.0”,
@capacitor/local-notifications”: “^5.0.0”,
@capacitor/push-notifications”: “^5.1.2”,
@capacitor/status-bar”: “^5.0.0”,
@capawesome/capacitor-file-picker”: “^0.5.0”,
@ionic-native/android-permissions”: “^5.36.0”,
@ionic-native/base64”: “^5.36.0”,
@ionic-native/camera”: “^5.36.0”,
@ionic-native/core”: “^5.36.0”,
@ionic-native/crop”: “^5.36.0”,
@ionic-native/device”: “^5.36.0”,
@ionic-native/document-scanner”: “^5.36.0”,
@ionic-native/downloader”: “^5.36.0”,
@ionic-native/file”: “^5.36.0”,
@ionic-native/file-opener”: “^5.36.0”,
@ionic-native/file-transfer”: “^5.36.0”,
@ionic-native/fingerprint-aio”: “^5.36.0”,
@ionic-native/http”: “^5.36.0”,
@ionic-native/multiple-document-picker”: “^5.36.0”,
@ionic-native/preview-any-file”: “^5.36.0”,
@ionic/angular”: “^6.0.0”,
@types/hammerjs”: “^2.0.41”,
“angular2-signaturepad”: “^4.0.2”,
“chart.js”: “^3.8.0”,
“com-badrit-base64”: “github:hazemhagrass/phonegap-base64”,
“cordova-plugin-advanced-http”: “^3.3.1”,
“cordova-plugin-android-permissions”: “^1.1.5”,
“cordova-plugin-app-version”: “^0.1.14”,
“cordova-plugin-background-mode”: “^0.7.3”,
“cordova-plugin-camera”: “^7.0.0”,
“cordova-plugin-camera-preview”: “^0.12.3”,
“cordova-plugin-chooser”: “^1.3.2”,
“cordova-plugin-crop”: “^0.4.0”,
“cordova-plugin-device”: “^2.1.0”,
“cordova-plugin-document-scanner”: “^4.2.7”,
“cordova-plugin-file”: “^8.1.3”,
“cordova-plugin-file-opener2”: “^4.0.0”,
“cordova-plugin-file-transfer”: “github:apache/cordova-plugin-file-transfer”,
“cordova-plugin-filepath”: “^1.6.0”,
“cordova-plugin-fingerprint-aio”: “^5.0.1”,
“cordova-plugin-inappbrowser”: “^5.0.0”,
“cordova-plugin-keyboard-scroll”: “^0.0.2”,
“cordova-plugin-multiple-documents-picker”: “^1.0.0”,
“cordova-plugin-preview-any-file”: “^0.2.9”,
“firebase”: “^10.3.0”,
“hammerjs”: “^2.0.8”,
“integrator-cordova-plugin-downloader”: “^1.1.0”,
“ion2-calendar”: “^3.5.0”,
“ionic-selectable”: “^4.9.0”,
“jquery”: “^3.6.0”,
“moment”: “^2.29.4”,
“ng2-charts”: “^3.1.2”,
“ng2-file-upload”: “^1.4.0”,
“ngx-device-detector”: “^3.0.0”,
“ngx-ionic-image-viewer”: “^0.7.5”,
“rxjs”: “~6.6.0”,
“timeago.js”: “^4.0.2”,
“tslib”: “^2.2.0”,
“zone.js”: “~0.11.4”
},
“devDependencies”: {
@angular-devkit/build-angular”: “~13.2.3”,
@angular-eslint/builder”: “~13.0.1”,
@angular-eslint/eslint-plugin”: “~13.0.1”,
@angular-eslint/eslint-plugin-template”: “~13.0.1”,
@angular-eslint/template-parser”: “~13.0.1”,
@angular/cli”: “~13.2.3”,
@angular/compiler”: “~13.2.2”,
@angular/compiler-cli”: “~13.2.2”,
@angular/language-service”: “~13.2.2”,
@capacitor/cli”: “^5.0.0”,
@ionic/angular-toolkit”: “^6.0.0”,
@types/googlemaps”: “^3.43.3”,
@types/jasmine”: “~3.6.0”,
@types/jasminewd2”: “~2.0.3”,
@types/jquery”: “^3.5.14”,
@types/node”: “^12.11.1”,
@typescript-eslint/eslint-plugin”: “5.3.0”,
@typescript-eslint/parser”: “5.3.0”,
“eslint”: “^7.6.0”,
“eslint-plugin-import”: “2.22.1”,
“eslint-plugin-jsdoc”: “30.7.6”,
“eslint-plugin-prefer-arrow”: “1.2.2”,
“jasmine-core”: “~3.8.0”,
“jasmine-spec-reporter”: “~5.0.0”,
“jetifier”: “^2.0.0”,
“karma”: “~6.3.2”,
“karma-chrome-launcher”: “~3.1.0”,
“karma-coverage”: “~2.0.3”,
“karma-coverage-istanbul-reporter”: “~3.0.2”,
“karma-jasmine”: “~4.0.0”,
“karma-jasmine-html-reporter”: “^1.5.0”,
“protractor”: “~7.0.0”,
“ts-node”: “~8.3.0”,
“typescript”: “^4.1.5”
},
“description”: “An Ionic project”
}

1 post - 1 participant

Read full topic

Auto-fill credential at login

$
0
0

Hello Everyone,
I have a demand from client to implement auto-fill password while user comes again to login and at first time app should display native popover to ask for save credentials to key-chain for ios and secure storage for android to use in future. I tried many ways like writing proper HTML input fields with appropriate attributes like autocomplete and textContentType.
Also in research I found an integration with associative domain to integrate auto-fill but still I am not able to make this workable. Please share your valuable suggestions.
I am using ionic(5) - capacitor(7) with angular.

Thanks and regards,
Parth

2 posts - 2 participants

Read full topic

Ion-datetime [isDateEnabled] does not visually remove disabled dates like [min] does

$
0
0

Description:
When using [min] on <ion-datetime>, dates before the minimum are visually removed from the calendar UI, making it clear to the user that those dates are not available. However, when using [isDateEnabled] to disable dates (including past dates), the calendar still displays those dates—they are just unselectable. This leads to inconsistent user experience: dates that should be unavailable are still visible, but cannot be selected.

Steps to reproduce:

  1. Use <ion-datetime [min]="today"> and observe that past dates are not shown in the calendar.
  2. Remove [min] and use only [isDateEnabled]="isDateEnabled" to block past dates.
    Note: If you use [min] together with [isDateEnabled], there will be a conflict and the calendar may behave unexpectedly.
  3. Notice that past dates are still visible, but cannot be selected.

Expected behavior:
Dates disabled by [isDateEnabled] should be visually removed from the calendar UI, just like dates blocked by [min].

Actual behavior:
Dates disabled by [isDateEnabled] are still visible in the calendar, but are unselectable.

Why this matters:

  • The user experience is inconsistent and confusing.
  • Using only [isDateEnabled] is necessary for complex logic (e.g., blocking ranges), but the UI is less clear than with [min].

Environment:

  • Ionic version: 8.x
  • Angular 19.x
  • Platform: Android/iOS/Web

Sample code:

      <ion-datetime
        id="datetimeStart"
        formControlName="start_date"
        display-format="DD/MM/YYYY"
        required
        locale="pt-BR"
        presentation="date"
        class="custom-datetime"
        [isDateEnabled]="isDateEnabled.bind(this)"
      ></ion-datetime>
  isDateEnabled(dateIsoString: string): boolean {
    const weeks = this.treinoForm.get('duration_weeks')?.value;
    if (!weeks) return true;

    const startDate = new Date(dateIsoString);
    const today = new Date(this.today);

    // Não permitir datas anteriores a hoje (Hack to replace [min])
    if (startDate < today) return false;

    const endDate = new Date(startDate);
    endDate.setDate(endDate.getDate() + weeks * 7 - 1);

    for (const period of this.blockedTrainingPeriods) {
      const blockedStart = new Date(period.startDate);
      const blockedEnd = new Date(period.endDate);

      if (startDate <= blockedEnd && endDate >= blockedStart) {
        return false;
      }
    }

    return true;
  }

1 post - 1 participant

Read full topic

How get know the country of the AppStore/Playstore the app was downloaded

$
0
0

To adhere to local laws (mostly EU/USA for now) I need to know which country store my app has been downloaded. How can I find this?

I only see implementations that use the local time zone, but that is not sufficient by Apple. Eg if someone is on holiday inside the EU, I should not be able to show that people are able to buy a subscription from the website.

Thank you!

2 posts - 2 participants

Read full topic

Is it recomendable to use Ionic 8?

$
0
0

Hello,

Im using Ionic 7 and I just saw it was already released for 1 year Ionic 8, I am scared about upgrading my app to this version and capacitor or google login wouldnt work, anyone can tell me if there are issues with it? thank you

2 posts - 2 participants

Read full topic


IonicFramework v8 cannot use WebSocket properly.But it runs normally in Chrome

$
0
0
useEffect(() => {
    const ws = new WebSocket("ws://192.168.2.174:9090");

    ws.onmessage = (event) => {
      const data = JSON.parse(event.data);
      console.log(data);
    };

    ws.onopen = () => {
      console.log("WebSocket 连接已打开");
    }

    ws.onclose = () => {
      console.log("WebSocket 连接已关闭");
    }

    ws.onerror = (error) => {
      console.log("WebSocket 连接出错", error);
    }

    return () => {
      ws.close();
    };
  }, [])

capacitor.config.ts

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'io.ionic.starter',
  appName: 'myApp',
  webDir: 'dist',
  plugins: {},
  server: {
    androidScheme: "http",
  }
};

export default config;

package.json

{
  "name": "myApp",
  "private": true,
  "version": "0.0.1",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "test.e2e": "cypress run",
    "test.unit": "vitest",
    "lint": "eslint"
  },
  "dependencies": {
    "@capacitor/android": "7.2.0",
    "@capacitor/app": "7.0.1",
    "@capacitor/browser": "^7.0.1",
    "@capacitor/core": "7.2.0",
    "@capacitor/haptics": "7.0.1",
    "@capacitor/keyboard": "7.0.1",
    "@capacitor/status-bar": "7.0.1",
    "@ionic/react": "^8.5.0",
    "@ionic/react-router": "^8.5.0",
    "@types/react-router": "^5.1.20",
    "@types/react-router-dom": "^5.3.3",
    "ionicons": "^7.4.0",
    "react": "19.0.0",
    "react-dom": "19.0.0",
    "react-router": "^5.3.4",
    "react-router-dom": "^5.3.4",
    "ros2d": "github:Neoplanetz/ros2djs-ros2",
    "ros3d": "^1.1.0",
    "roslib": "^1.4.1",
    "vconsole": "^3.15.1",
    "zustand": "^5.0.5"
  },
  "devDependencies": {
    "@capacitor/cli": "7.2.0",
    "@testing-library/dom": ">=7.21.4",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^16.2.0",
    "@testing-library/user-event": "^14.4.3",
    "@types/react": "19.0.10",
    "@types/react-dom": "19.0.4",
    "@types/roslib": "^1.3.5",
    "@vitejs/plugin-legacy": "^5.0.0",
    "@vitejs/plugin-react": "^4.0.1",
    "cypress": "^13.5.0",
    "eslint": "^9.20.1",
    "eslint-plugin-react": "^7.32.2",
    "eslint-plugin-react-hooks": "^5.1.0",
    "eslint-plugin-react-refresh": "^0.4.19",
    "globals": "^15.15.0",
    "jsdom": "^22.1.0",
    "terser": "^5.4.0",
    "typescript": "^5.1.6",
    "typescript-eslint": "^8.24.0",
    "vite": "~5.2.0",
    "vitest": "^0.34.6"
  },
  "description": "An Ionic project"
}

1 post - 1 participant

Read full topic

ionChange triggering in wrong ion-radio-group

Prakash Hinduja Geneva, Switzerland - How to fix slow loading time in Ionic Angular app?

$
0
0

I’m Prakash Hinduja Geneva, Switzerland and experiencing slow loading times in my Ionic Angular app, especially on initial launch. I’ve tried basic optimizations but haven’t seen much improvement. I’m looking for advice, best practices, or tools to boost performance and reduce load time. Any support from the Ionic community would be greatly appreciated.

Regards
Prakash Hinduja Geneva, Switzerland

1 post - 1 participant

Read full topic

Image Preview Modal - Centering Image Across Full Screen with Header

$
0
0

Hello,

I’m trying to implement a full-screen image preview modal. My current implementation, even with ion-content padding removed and height: 100% on the image container, doesn’t center the image truly across the entire screen. It appears to be centered only within the ion-content area, below where the ion-header sits, pushing the image down.

What I’ve tried:

  • Using position: fixed or position: absolute within the ion-header. This allows the image to center on the full screen, but I’m unsure if this is considered a good practice.
  • Omitting ion-header entirely and attempting to create a custom top bar (with a close button) using position: absolute or fixed directly within the modal’s main template.

I’m looking for the most robust and recommended approach to achieve true full-screen image centering in an Ionic modal, ensuring the ion-header (ideally transparent) can float over the image without affecting its vertical alignment.

1 post - 1 participant

Read full topic

A basic component w/ a column of icons and a list side to side

$
0
0

I’m Pretty new to ionic angular and not much of UI dev, so I hope I can get some help.

I want to make a component that has two vertical columns in my
a. a vertical column of approximately 8-12 buttons (with an SVG in each of them), just wide enough for the column of ion-buttons.

b. An ion-list of ion-item natively styled with a button or two and one line of text in the item) but I think I understand making a .
Let’s call a. the selection and b. the results.

Q1: What do I wrap the with to make them a vertical column each the same width?
DO I use <ion-list lines=“none” …> is that overkill or just right? Do I then put that list in an ion-content to get scrolling if needed? I really don’t need space between the icons, but maybe I’m fighting the native styling if I don’t have/want space. Alternatively, do I use a with one per icon button?

Q2: I can’t seem to get my head around what to wrap both sides of this component with to make them play properly as a responsive web design.
Q2 Choice 1. 1 Don’t worry two lists (or a grid and a list) will end up next to each other.
Q2 Choice 2. Some divs and some css will make them next to each other.
Q2 Choice 3. put everything in a one-row, two-column ion-grid.

Here is closest Q on the forum to this but it is from 2014 (!).

Q3: Is ion-content in ion-content valid?
Yes, I will actually make three separate components: 1. the selection list and 2. the results list, both in 3. the whole screen/page (with a title etc.)

TIA,

1 post - 1 participant

Read full topic

Viewing all 49385 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>