iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Examples

Six pasteable Ionic patterns: a tab-based shell, page navigation with params, a form with a toast, an HTTP client with auth, an infinite-scroll list, and the Capacitor camera. Ionic v7 with Angular standalone components.

Six working Ionic snippets

EXAMPLE
// 1) App shell with tabs
// app.routes.ts
// import { Routes } from '@angular/router';
// export const routes: Routes = [
//   { path: '', loadComponent: () => import('./tabs/tabs.page').then(m => m.TabsPage),
//     children: [
//       { path: '', redirectTo: 'home', pathMatch: 'full' },
//       { path: 'home',    loadComponent: () => import('./home/home.page').then(m => m.HomePage) },
//       { path: 'catalog', loadComponent: () => import('./catalog/catalog.page').then(m => m.CatalogPage) },
//       { path: 'orders',  loadComponent: () => import('./orders/orders.page').then(m => m.OrdersPage) },
//     ]
//   },
// ];

// tabs.page.html
// <ion-tabs>
//   <ion-tab-bar slot='bottom'>
//     <ion-tab-button tab='home'><ion-icon name='home'/><ion-label>Home</ion-label></ion-tab-button>
//     <ion-tab-button tab='catalog'><ion-icon name='bag'/><ion-label>Catalog</ion-label></ion-tab-button>
//     <ion-tab-button tab='orders'><ion-icon name='receipt'/><ion-label>Orders</ion-label></ion-tab-button>
//   </ion-tab-bar>
// </ion-tabs>

// 2) Page navigation with params
// catalog.page.ts
// constructor(private router: Router) {}
// openProduct(sku: string) { this.router.navigate(['/products', sku]); }
//
// app.routes.ts
// { path: 'products/:sku', loadComponent: () => import('./product/product.page').then(m => m.ProductPage) }
//
// product.page.ts
// import { ActivatedRoute } from '@angular/router';
// constructor(private route: ActivatedRoute) {}
// sku = this.route.snapshot.paramMap.get('sku')!;

// 3) Form + toast
// import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
// import { ToastController } from '@ionic/angular/standalone';
//
// form = this.fb.group({
//   email: ['', [Validators.required, Validators.email]],
//   password: ['', [Validators.required, Validators.minLength(8)]],
// });
//
// async submit() {
//   if (this.form.invalid) return;
//   try {
//     await this.api.login(this.form.getRawValue());
//     (await this.toast.create({ message: 'Welcome back', duration: 2000, color: 'success' })).present();
//   } catch (e: any) {
//     (await this.toast.create({ message: e.message, duration: 3000, color: 'danger' })).present();
//   }
// }

// 4) HTTP client with bearer auth
// @Injectable({ providedIn: 'root' })
// export class Api {
//   constructor(private http: HttpClient, private secure: Secure) {}
//
//   private async authHeaders() {
//     const token = await this.secure.getToken();
//     return { Authorization: 'Bearer ' + (token ?? '') };
//   }
//
//   async listOrders(): Promise<Order[]> {
//     return firstValueFrom(this.http.get<Order[]>('/api/orders', { headers: await this.authHeaders() }));
//   }
// }

// 5) Infinite scroll list
// <ion-content>
//   <ion-list>
//     <ion-item *ngFor='let o of orders'>
//       <ion-label>{{ o.customer }} — {{ o.total | currency:'AUD' }}</ion-label>
//     </ion-item>
//   </ion-list>
//   <ion-infinite-scroll (ionInfinite)='loadMore($event)'>
//     <ion-infinite-scroll-content loadingText='Loading...'></ion-infinite-scroll-content>
//   </ion-infinite-scroll>
// </ion-content>
//
// async loadMore(ev: any) {
//   const next = await this.api.listOrders({ cursor: this.cursor });
//   this.orders.push(...next.data);
//   this.cursor = next.nextCursor;
//   ev.target.complete();
//   if (!this.cursor) ev.target.disabled = true;
// }

// 6) Capacitor camera
// import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
//
// async takePhoto() {
//   const photo = await Camera.getPhoto({
//     resultType: CameraResultType.DataUrl,
//     source: CameraSource.Camera,
//     quality: 80,
//   });
//   this.preview = photo.dataUrl;
// }

// 7) Decision matrix
// - Tabs                -> ion-tabs with router children
// - Modal forms          -> ModalController + ion-modal
// - Toasts / loading     -> ToastController / LoadingController
// - Bottom-sheet         -> ion-modal initialBreakpoint
// - Page-level scrolling -> ion-content; avoid nested scrolling containers

// 8) Pitfalls
// - Nested scroll containers inside ion-content
// - Forgetting 'await loading.present()' before async work
// - Manual style overrides that break theme variables; use --ion-color-* CSS variables
// - Storing tokens in localStorage; use Capacitor Preferences or secure storage

Why it matters

Use Ionic primitives (ion-content, ion-toast, ion-modal) instead of hand-rolling equivalents. They handle keyboard avoidance, safe area, ripple feedback, and dark mode automatically — and they look right on both iOS and Android without per-platform tweaks. Resist the urge to style around them; bend them with CSS variables instead.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Photo gallery, todo list, location tracker, push-enabled chat.
Try it Yourself »

Discussion

Loading…