{"id":17366786,"url":"https://github.com/thirdygayares/angular-rxjs-basics","last_synced_at":"2026-02-03T23:32:36.452Z","repository":{"id":256366202,"uuid":"855055729","full_name":"thirdygayares/angular-rxjs-basics","owner":"thirdygayares","description":"Basic Angular application that demonstrates the use of RxJS to handle asynchronous data streams.","archived":false,"fork":false,"pushed_at":"2024-09-16T00:52:42.000Z","size":132,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-06T08:03:45.274Z","etag":null,"topics":["angular","angular-basics","angular-foundation","angular-rxjs","angular-rxjs-basic"],"latest_commit_sha":null,"homepage":"https://software-engineer.thirdygayares.com/angular-rxjs-basics","language":"HTML","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/thirdygayares.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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-10T08:21:40.000Z","updated_at":"2024-09-16T00:52:45.000Z","dependencies_parsed_at":"2024-09-10T10:45:22.269Z","dependency_job_id":"3ba2d638-71f4-4983-a1a5-cdc2c07a7dd3","html_url":"https://github.com/thirdygayares/angular-rxjs-basics","commit_stats":{"total_commits":3,"total_committers":2,"mean_commits":1.5,"dds":"0.33333333333333337","last_synced_commit":"e709125f74a0acd58ddc47b1e86c9ea41122aa32"},"previous_names":["thirdygayares/angular-rxjs-basics"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thirdygayares/angular-rxjs-basics","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdygayares%2Fangular-rxjs-basics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdygayares%2Fangular-rxjs-basics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdygayares%2Fangular-rxjs-basics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdygayares%2Fangular-rxjs-basics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thirdygayares","download_url":"https://codeload.github.com/thirdygayares/angular-rxjs-basics/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdygayares%2Fangular-rxjs-basics/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29061562,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T23:14:54.203Z","status":"ssl_error","status_checked_at":"2026-02-03T23:14:50.873Z","response_time":96,"last_error":"SSL_read: 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","angular-basics","angular-foundation","angular-rxjs","angular-rxjs-basic"],"created_at":"2024-10-15T22:04:53.694Z","updated_at":"2026-02-03T23:32:36.435Z","avatar_url":"https://github.com/thirdygayares.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"Building a simple application that fetches data from an API and displays it in a component. We'll use RxJS operators like `Observable`, `BehaviorSubject`, and `catchError` to handle data streams and errors.\n\nThe tutorial covers:\n\n1. **Introduction to RxJS in simple terms**\n    \n2. **Setting up a basic Angular app**\n    \n3. **Creating a simple API service using HttpClient**\n    \n4. **Handling API responses with RxJS Observables**\n    \n5. **Handling errors using RxJS**\n    \n\n# Introduction to RxJS\n\n**RxJS** (Reactive Extensions for JavaScript) is a library used with **Angular** to handle asynchronous events and data streams. Think of it as a way to manage and respond to things happening in your app, like API responses, user inputs, or other async tasks.\n\n* **Observable**: This is like a stream of data. It can emit multiple values over time (such as API data).\n    \n* **BehaviorSubject**: It's like an Observable but has an initial value and can emit new values when updated.\n    \n* **catchError**: It is used to catch and handle errors in the Observable stream.\n    \n\n# File Structure\n\n![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725955774130/ec52bc23-f854-4e09-9479-00f853ad50ad.png)\n\n### Step-by-Step Code Explanation\n\n# 1\\. **Post Model**\n\nThis model represents the structure of a **Post** object that we will receive from the API.\n\n```typescript\nexport interface Post {\n  userId: number;\n  id: number;\n  title: string;\n  body: string;\n}\n```\n\n# 2\\. **Post Service**\n\nIn this service, we will fetch the posts from a fake online API ([`jsonplaceholder.typicode.com`](http://jsonplaceholder.typicode.com)) using **HttpClient**.\n\n* **getPosts()** method fetches data from the API as an **Observable** of an array of `Post[]`.\n    \n\n```typescript\nimport { Injectable } from '@angular/core';\nimport { HttpClient } from \"@angular/common/http\";\nimport { Observable } from \"rxjs\";\nimport { Post } from \"../models/post.model\";\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class PostService {\n  private apiUrl = 'https://jsonplaceholder.typicode.com/posts';\n\n  constructor(private http: HttpClient) {}\n\n  getPosts(): Observable\u003cPost[]\u003e {\n    return this.http.get\u003cPost[]\u003e(this.apiUrl);\n  }\n}\n```\n\n# 3\\. **App Component**\n\nIn this component, we will:\n\n* Fetch the posts using the `PostService`.\n    \n* Use **RxJS** to handle the data and errors.\n    \n* Display the posts in the template.\n    \n\n##### app.component.ts\n\nIn the `ngOnInit` lifecycle hook, we subscribe to the `getPosts()` method and handle any errors using **catchError**.\n\n```typescript\nimport { Component, OnInit } from '@angular/core';\nimport { BehaviorSubject, catchError, Observable } from \"rxjs\";\nimport { Post } from \"./models/post.model\";\nimport { PostService } from \"./services/post.service\";\n\n@Component({\n  selector: 'app-root',\n  templateUrl: './app.component.html',\n  styleUrls: ['./app.component.css']\n})\nexport class AppComponent implements OnInit {\n  posts$: Observable\u003cPost[]\u003e | undefined;\n\n  private errorSubject = new BehaviorSubject\u003cstring | null\u003e(null);\n  error$ = this.errorSubject.asObservable();\n\n  constructor(private postService: PostService) {}\n\n  ngOnInit(): void {\n    this.posts$ = this.postService.getPosts().pipe(\n      catchError(err =\u003e {\n        this.errorSubject.next(err.message);\n        return [];\n      })\n    );\n  }\n}\n```\n\n# 4\\. **Template (HTML)**\n\nThe template will display:\n\n* A list of posts from the `posts$` observable.\n    \n* An error message if something goes wrong.\n    \n\n```typescript\n\u003cdiv *ngIf=\"error$ | async as error\"\u003e\n  \u003cdiv\u003e\n    {{ error }}\n  \u003c/div\u003e\n\u003c/div\u003e\n\n\u003cul *ngIf=\"posts$ | async as posts\"\u003e\n  \u003cli *ngFor=\"let post of posts\"\u003e\n    \u003ch3\u003e {{ post.title }} \u003c/h3\u003e\n    \u003cp\u003e {{ post.body }} \u003c/p\u003e\n  \u003c/li\u003e\n\u003c/ul\u003e\n```\n\n# 5\\. **App Module**\n\nThe module is where we import required Angular libraries like `BrowserModule`, `RouterModule`, and `HttpClientModule`.\n\n```typescript\nimport { NgModule } from '@angular/core';\nimport { BrowserModule } from '@angular/platform-browser';\nimport {RouterModule, Routes} from '@angular/router';\nimport {CommonModule} from \"@angular/common\";\nimport {AppComponent} from \"./app.component\";\nimport {provideAnimationsAsync} from \"@angular/platform-browser/animations/async\";\nimport {PostService} from \"./services/post.service\";\nimport { provideHttpClient} from \"@angular/common/http\";\n\nconst routes: Routes = [\n  { path: '', component: AppComponent },\n];\n\n@NgModule({\n  imports: [\n    CommonModule,\n    BrowserModule,\n    RouterModule.forRoot(routes, {enableTracing: true}),\n  ],\n\n  exports: [RouterModule],\n\n  declarations: [\n  AppComponent,\n],\n  providers: [\n  provideAnimationsAsync(),\n    PostService,\n    provideHttpClient()\n  ],\n\n  bootstrap: [\n  AppComponent\n  ]\n  \n})\nexport class AppModule { }\n\n```\n\n### How the App Works\n\n1. **Service**: The `PostService` fetches posts from the API using **HttpClient**.\n    \n2. **Component**: In `AppComponent`, we subscribe to the posts observable and display them in the HTML.\n    \n3. **Template**: The template displays the posts and also shows an error if something goes wrong using `BehaviorSubject` and `catchError`.\n    \n\n# **OUTPUT**\n\n![](https://cdn.hashnode.com/res/hashnode/image/upload/v1725955708707/7954cc4a-22c5-45dd-a9dd-d5079c9c658d.png)\n\nA list of **posts**, each consisting of a title and body, fetched from an API [`jsonplaceholder.typicode.com`](http://jsonplaceholder.typicode.com), which provides mock data for testing purposes.\n\n# GitHub Link:\n\n%[https://github.com/thirdygayares/Angular-Components-Modules-Routing.git]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdygayares%2Fangular-rxjs-basics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthirdygayares%2Fangular-rxjs-basics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdygayares%2Fangular-rxjs-basics/lists"}