{"id":14994045,"url":"https://github.com/tech-andgar/ionic-angular-todo-app","last_synced_at":"2026-03-15T07:32:17.612Z","repository":{"id":256119701,"uuid":"853918932","full_name":"tech-andgar/ionic-angular-todo-app","owner":"tech-andgar","description":"📋 App created using the Ionic framework, using a firebase cloud database to store to-do data. All CRUD operations can be carried out using the Ionic UI.","archived":false,"fork":false,"pushed_at":"2024-09-09T04:47:38.000Z","size":34359,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-08T16:34:45.332Z","etag":null,"topics":["angular","ionic","ionic-framework","todo"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tech-andgar.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-07T22:40:20.000Z","updated_at":"2024-09-09T04:47:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"69d7cb82-8781-4403-9939-b37c9d19fb57","html_url":"https://github.com/tech-andgar/ionic-angular-todo-app","commit_stats":{"total_commits":1,"total_committers":1,"mean_commits":1.0,"dds":0.0,"last_synced_commit":"25e777a2eb8b22a41a84bd9cda00ba4da95b8e63"},"previous_names":["tech-andgar/ionic-angular-todo-app"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tech-andgar/ionic-angular-todo-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tech-andgar%2Fionic-angular-todo-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tech-andgar%2Fionic-angular-todo-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tech-andgar%2Fionic-angular-todo-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tech-andgar%2Fionic-angular-todo-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tech-andgar","download_url":"https://codeload.github.com/tech-andgar/ionic-angular-todo-app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tech-andgar%2Fionic-angular-todo-app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30537655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-15T07:17:37.589Z","status":"ssl_error","status_checked_at":"2026-03-15T07:17:31.738Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","ionic","ionic-framework","todo"],"created_at":"2024-09-24T15:34:01.679Z","updated_at":"2026-03-15T07:32:17.593Z","avatar_url":"https://github.com/tech-andgar.png","language":"TypeScript","readme":"# # :zap: Ionic Todo App\n\n## Overview\n\nThis project is a Todo App developed with Ionic, TypeScript, and Angular. It features a robust interface for managing todo items, including creating, reading, updating, and deleting them, as well as performing batch operations and managing resources. The app uses a Firebase cloud database for data storage and the [Ionic framework](https://ionicframework.com/docs) for its UI. The API is designed to be flexible and consistent, supporting various implementations while maintaining a unified interface.\n\n- All CRUD operations can be performed through the Ionic UI.\n- **Note:** To open web links in a new window, use _ctrl+click_ on the link.\n\n![GitHub repo size](https://img.shields.io/github/repo-size/tech-andgar/ionic-angular-todo-app?style=plastic)\n![GitHub pull requests](https://img.shields.io/github/issues-pr/tech-andgar/ionic-angular-todo-app?style=plastic)\n![GitHub Repo stars](https://img.shields.io/github/stars/tech-andgar/ionic-angular-todo-app?style=plastic)\n![GitHub last commit](https://img.shields.io/github/last-commit/tech-andgar/ionic-angular-todo-app?style=plastic)\n\n## :page_facing_up: Table of contents\n\n- [# :zap: Ionic Todo App](#-zap-ionic-todo-app)\n  - [Overview](#overview)\n  - [:page\\_facing\\_up: Table of contents](#page_facing_up-table-of-contents)\n  - [:cool: Features](#cool-features)\n  - [📦 Installation Offline](#-installation-offline)\n  - [:camera: Screenshots](#camera-screenshots)\n  - [:signal\\_strength: Technologies](#signal_strength-technologies)\n  - [🌳 Project Structure](#-project-structure)\n  - [:floppy\\_disk: Setup / Installation](#floppy_disk-setup--installation)\n  - [Usage](#usage)\n  - [Key Components](#key-components)\n  - [📚 API Reference](#-api-reference)\n    - [TodosApi](#todosapi)\n      - [Todo Retrieval Methods](#todo-retrieval-methods)\n      - [Todo Modification Methods](#todo-modification-methods)\n      - [Todo Deletion Methods](#todo-deletion-methods)\n      - [Batch Operations Methods](#batch-operations-methods)\n      - [Resource Management Methods](#resource-management-methods)\n  - [:computer: Code Examples - Implementation Details](#computer-code-examples---implementation-details)\n    - [LocalStorageTodosApi](#localstoragetodosapi)\n  - [🧪 Testing](#-testing)\n  - [⚠️ Performance Considerations](#️-performance-considerations)\n  - [:clipboard: Status \\\u0026 To-do list](#clipboard-status--to-do-list)\n  - [Contributing](#contributing)\n  - [:file\\_folder: License](#file_folder-license)\n  - [:envelope: Contact](#envelope-contact)\n\n## :cool: Features\n\n**CRUD operations:**\n\n- Create: Click '+' to create a to-do item.\n- Read: Line items are displayed on the home page.\n- Update: Click on item line to edit.\n- Delete: swipe left and a colored 'DONE' button appears on the right.\n- Batch operations (clear completed, complete all)\n- Observable-based API for reactive programming\n- Local storage persistence\n- TypeScript for type safety\n- Abstract API design for flexibility in implementation\n\n## 📦 Installation Offline\n\n- [ANDROID APK (UNSIGNED)](./docs/installer/android/)\n\n- [IOS IPA (UNSIGNED)](./docs/installer/ios/)\n\n## :camera: Screenshots\n\n![todo items shown on ionic frontend and Firestore database](./docs/imgs/todo-app-multilanguage.png)\n![todo items shown on ionic frontend and Firestore database](./docs/imgs/todo-app-web.png)\n![todo items shown on ionic frontend and Firestore database](./docs/imgs/todo-app-category.png)\n![todo items shown on ionic frontend and Firestore database](./docs/imgs/todo-app-filter-category.png)\n![todo items shown on ionic frontend and Firestore database](./docs/imgs/todo-app-slide.png)\n![todo items shown on ionic frontend and Firestore database](./docs/imgs/todo-app-options.png)\n![todo items shown on ionic frontend and Firestore database](./docs/imgs/todo-app-undo.png)\n![todo](./docs/video/todo-app.mp4)\n\n## :signal_strength: Technologies\n\n- [Ionic/angular v8](https://ionicframework.com/)\n- [Ionic v8](https://ionicframework.com/)\n- [Angular v18](https://angular.io/)\n- [Firebase cloudstore v10](https://firebase.google.com/)\n\n## 🌳 Project Structure\n\n```\ntodo/\n├── src\n│   ├── app\n│   │   ├── app.component.html\n│   │   ├── app.component.scss\n│   │   ├── app.component.spec.ts\n│   │   ├── app.component.ts\n│   │   ├── app.routes.ts\n│   │   ├── core\n│   │   │   ├── domain\n│   │   │   │   ├── api\n│   │   │   │   │   └── todos_api.ts\n│   │   │   │   ├── exceptions\n│   │   │   │   │   └── exceptions.ts\n│   │   │   │   └── model\n│   │   │   │       ├── category.model.ts\n│   │   │   │       ├── json_map.ts\n│   │   │   │       └── todo.model.ts\n│   │   │   ├── language\n│   │   │   │   ├── language-switcher.component.ts\n│   │   │   │   ├── language.service.ts\n│   │   │   │   └── model\n│   │   │   │       └── language.model.ts\n│   │   │   ├── settings\n│   │   │   │   └── settings-dropdown.component.ts\n│   │   │   └── theme\n│   │   │       ├── theme-switcher.component.ts\n│   │   │       └── theme.service.ts\n│   │   └── features\n│   │       ├── categories\n│   │       │   ├── data\n│   │       │   │   ├── infrastructure\n│   │       │   │   │   └── local-storage-api\n│   │       │   │   │       └── local.storage.categories.api.ts\n│   │       │   │   └── repository\n│   │       │   │       └── categories-repository-impl.ts\n│   │       │   ├── domain\n│   │       │   │   ├── infrastructure\n│   │       │   │   │   └── categories_api.ts\n│   │       │   │   └── repository\n│   │       │   │       └── categories_repository.ts\n│   │       │   └── presentation\n│   │       │       └── category-list\n│   │       │           ├── category-list.page.ts\n│   │       │           └── category-list.service.ts\n│   │       ├── home\n│   │       │   └── presentation\n│   │       │       └── home.page.ts\n│   │       └── todos\n│   │           ├── data\n│   │           │   ├── infrastructure\n│   │           │   │   └── local_storage\n│   │           │   │       └── local.storage.todos.api.ts\n│   │           │   └── repository\n│   │           │       └── todos-repository-impl.ts\n│   │           ├── domain\n│   │           │   └── repository\n│   │           │       └── todos_repository.ts\n│   │           └── presentation\n│   │               ├── components\n│   │               │   ├── category-badge.component.ts\n│   │               │   ├── category-filter.component.ts\n│   │               │   ├── stats\n│   │               │   │   ├── stats.component.ts\n│   │               │   │   └── stats.service.ts\n│   │               │   ├── todo-list-item\n│   │               │   │   ├── todo-list-item.component.ts\n│   │               │   │   └── todo-list-item.service.ts\n│   │               │   ├── todos-overview-filter-button.component.ts\n│   │               │   └── todos-overview-options-button.component.ts\n│   │               ├── edit-todo\n│   │               │   ├── edit-todo.page.ts\n│   │               │   └── edit-todo.service.ts\n│   │               └── todos-overview\n│   │                   ├── todos-overview.page.ts\n│   │                   └── todos-overview.service.ts\n│   ├── app.config.ts\n│   ├── assets\n│   │   ├── i18n\n│   │   │   ├── en.json\n│   │   │   └── es.json\n│   │   ├── icon\n│   │   │   └── favicon.png\n│   │   └── shapes.svg\n│   ├── environments\n│   │   ├── environment.prod.ts\n│   │   └── environment.ts\n│   ├── global.scss\n│   ├── index.html\n│   ├── main.ts\n│   ├── polyfills.ts\n│   ├── test.ts\n│   ├── theme\n│   │   └── variables.scss\n│   └── zone-flags.ts\n├── tsconfig.app.json\n├── tsconfig.json\n└── tsconfig.spec.json\n```\n\n- `todo.model.ts`: Defines the `Todo` interface\n- `todos.api.ts`: Contains the abstract `TodosApi` class\n- `local-storage-todos.api.ts`: Implements `TodosApi` using local storage\n\n## :floppy_disk: Setup / Installation\n\n1. Clone the repository:\n\n   ```shell\n   git clone https://github.com/tech-andgar/todo-api-project.git\n   ```\n\n2. Navigate to the project directory:\n\n   ```shell\n   cd todo-api-project\n   ```\n\n3. Install dependencies:\n\n   ```shell\n   pnpm i\n   ```\n\n   or\n\n   ```shell\n   yarn i\n   ```\n\n   or\n\n   ```shell\n   npm i\n   ```\n\n4. Add firebase access credentials in:\n\n   `environment.ts`\n\n5. Run the development server on _localhost://8100_:\n\n   ``` shell\n   ionic serve\n   ```\n\n6. Create build artifacts in `www` folder:\n\n   ``` shell\n   npm run build\n   ```\n\n## Usage\n\nTo use the Todo API in your Angular application, inject the `TodosApi` service into your component or service:\n\n```typescript\nimport { Component } from '@angular/core';\nimport { TodosApi } from './path-to-todos-api';\nimport { Todo } from './path-to-todo-model';\n\n@Component({\n  selector: 'app-todo-list',\n  template: '...'\n})\nexport class TodoListComponent {\n  todos: Todo[] = [];\n\n  constructor(private todosApi: TodosApi) {\n    this.todosApi.getTodos().subscribe(todos =\u003e this.todos = todos);\n  }\n\n  addTodo(todo: Todo) {\n    this.todosApi.saveTodo(todo).subscribe(success =\u003e {\n      if (success) {\n        console.log('Todo added successfully');\n      }\n    });\n  }\n}\n```\n\n## Key Components\n\n1. `core/domain/model/todo.model.ts`: Defines the `Todo` interface.\n2. `core/api/todos.api.ts`: Abstract class defining the API for managing todos.\n3. `data/api/local-storage-todos.api.ts`: Concrete implementation of `TodosApi` using local storage.\n4. `features/todo/`: Contains components, services, and module for the todo feature.\n\n## 📚 API Reference\n\n### TodosApi\n\nThe `TodosApi` abstract class provides the following methods:\n\n#### Todo Retrieval Methods\n\n- `getTodos(): Observable\u003cTodo[]\u003e`\n  - Provides an Observable of all todos.\n\n- `getTodo(todoId: string): Observable\u003cTodo\u003e`\n  - Retrieves a todo by its ID.\n\n#### Todo Modification Methods\n\n- `saveTodo(todo: Todo): Observable\u003cboolean\u003e`\n  - Saves a todo. If a todo with the same ID already exists, it will be replaced.\n\n- `saveTodoAt(todo: Todo, index: number | null): Observable\u003cboolean\u003e`\n  - Saves a todo at a specified index. If a todo with the same ID already exists, it will be replaced.\n\n#### Todo Deletion Methods\n\n- `deleteTodo(id: string): Observable\u003cboolean\u003e`\n  - Deletes the todo with the given ID.\n\n#### Batch Operations Methods\n\n- `clearCompleted(): Observable\u003cnumber\u003e`\n  - Deletes all completed todos.\n\n- `completeAll(isCompleted: boolean): Observable\u003cnumber\u003e`\n  - Sets the `isCompleted` state of all todos to the given value.\n\n#### Resource Management Methods\n\n- `close(): Observable\u003cvoid\u003e`\n  - Closes the API client and frees up any resources.\n\n## :computer: Code Examples - Implementation Details\n\n### LocalStorageTodosApi\n\nThe `LocalStorageTodosApi` class implements the `TodosApi` abstract class using browser's local storage for persistence. Key features include:\n\n- Uses `BehaviorSubject` to manage the stream of todos\n- Implements all abstract methods from `TodosApi`\n- Persists todos to local storage after each operation\n- Retrieves todos from local storage on initialization\n\nExample of saving a todo:\n\n```typescript\nsaveTodo(todo: Todo): Observable\u003cboolean\u003e {\n  const todos = [...this.todoStreamController.value];\n  const todoIndex = todos.findIndex(t =\u003e t.id === todo.id);\n  if (todoIndex \u003e= 0) {\n    todos[todoIndex] = todo;\n  } else {\n    todos.push(todo);\n  }\n\n  this.todoStreamController.next(todos);\n  localStorage.setItem(LocalStorageTodosApi.kTodosCollectionKey, JSON.stringify(todos));\n\n  return this.getTodo(todo.id).pipe(map(todo =\u003e !!todo));\n}\n```\n\n## 🧪 Testing\n\nTo run the tests for this project:\n\n```shell\nng test\n```\n\nWe use Jasmine for unit testing and Karma as the test runner. Key areas to test include:\n\n- Individual CRUD operations\n- Batch operations\n- Edge cases (e.g., deleting non-existent todos)\n- Local storage persistence\n\n## ⚠️ Performance Considerations\n\n- The current implementation loads all todos into memory, which may not be optimal for large datasets.\n- Consider implementing pagination or virtual scrolling for better performance with large lists.\n- Local storage has limited capacity; for larger applications, consider using IndexedDB or a backend server.\n\n## :clipboard: Status \u0026 To-do list\n\n- Status: Working.\n- To-do:\n  - [ ] Implementation Firestore\n  - [ ] Implementation Feature Flag\n  - [ ] Testing\n\u003c!-- - To-do: Add more detail/styling to front page. Add ESLint. Limit priority number to `1 to 10` --\u003e\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the project\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n\u003c!-- ## :clap: Inspiration\n\n- Project inspired by [Simon Grimm´s Youtube video 'How to Create a Simple Ionic 4 App with Firebase and AngularFire'](https://www.youtube.com/watch?v=H20l9ofyR54\u0026t=1375s) --\u003e\n\n## :file_folder: License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.\n\n## :envelope: Contact\n\nRepo created by [TECH-ANDGAR](https://github.com/tech-andgar), email: \u003cdev@tech-andgar.me\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftech-andgar%2Fionic-angular-todo-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftech-andgar%2Fionic-angular-todo-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftech-andgar%2Fionic-angular-todo-app/lists"}