> For the complete documentation index, see [llms.txt](https://odilbeks-organization.gitbook.io/angular-ustoz-shogirt/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://odilbeks-organization.gitbook.io/angular-ustoz-shogirt/componentlararo-malumot-almashish.-servicega-kirish.md).

# Componentlararo ma'lumot almashish. Servicega kirish

#### Mundarija

1. **Componentalar o’rtasida ma’lumot almashish**
   * @Input() - parent dan child ga ma'lumot
   * @Output() va EventEmitter - child dan parent ga
   * ViewChild va ViewChildren
2. **Service nima?**
   * Dependency Injection
   * Service yaratish: `ng generate service`
   * providedIn: 'root'
3. **Data sharing:**
   * Service orqali ma'lumot almashish
   * ~~BehaviorSubject va Observable~~ (Mustaqil o'rganish uchun)

***

### 1. **Componentalar o’rtasida ma’lumot almashish**

Angular ilovasida ko'pincha bir nechta komponentlar bir-biri bilan ma'lumot almashishlari kerak bo'ladi. Buning uchun turli usullar mavjud.

#### 1.1 @Input() - Parent dan Child ga ma'lumot uzatish

`@Input()` decorator yordamida parent komponent child komponentga ma'lumot yuborishi mumkin.

#### Oddiy misol:

**Child Component (student-card.component.ts):**

```tsx
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-student-card',
  templateUrl: './student-card.component.html',
  styleUrls: ['./student-card.component.css']
})
export class StudentCardComponent {
  @Input() studentName: string = '';
  @Input() score: number = 0;
  @Input() grade: string = '';
}
```

**Child Template (student-card.component.html):**

```html
<div class="student-card">
  <h3>{{ studentName }}</h3>
  <p>Ball: {{ score }}</p>
  <p>Baho: {{ grade }}</p>
</div>
```

**Parent Component (students-list.component.ts):**

```tsx
import { Component } from '@angular/core';

@Component({
  selector: 'app-students-list',
  templateUrl: './students-list.component.html'
})
export class StudentsListComponent {
  students = [
    { name: 'Ali Valiyev', score: 95, grade: 'A' },
    { name: 'Gulnora Karimova', score: 87, grade: 'B' },
    { name: 'Sardor Rahimov', score: 78, grade: 'C' }
  ];
}
```

**Parent Template (students-list.component.html):**

```html
<div class="students-container">
  <h2>Talabalar ro'yxati</h2>

  @for (student of students; track student.name) {
    <app-student-card
      [studentName]="student.name"
      [score]="student.score"
      [grade]="student.grade">
    </app-student-card>
  }
</div>
```

#### @Input() bilan alias (taxallus) ishlatish:

```tsx
export class StudentCardComponent {
  @Input('pupilName') studentName: string = '';  // pupilName deb chaqirish mumkin
}
```

```html
<app-student-card [pupilName]="student.name"></app-student-card>
```

#### @Input() bilan setter ishlatish:

```tsx
export class StudentCardComponent {
  private _score: number = 0;

  @Input()
  set score(value: number) {
    this._score = value;
    this.updateGrade();  // Score o'zgarganda avtomatik yangilanadi
  }

  get score(): number {
    return this._score;
  }

  grade: string = '';

  updateGrade() {
    if (this._score >= 90) this.grade = 'A';
    else if (this._score >= 75) this.grade = 'B';
    else if (this._score >= 60) this.grade = 'C';
    else this.grade = 'F';
  }
}
```

***

#### 1.2 @Output() va EventEmitter - Child dan Parent ga ma'lumot yuborish

`@Output()` decorator va `EventEmitter` yordamida child komponent parent komponentga hodisalar (events) yuborishi mumkin.

#### Asosiy misol:

**Child Component (calculator-button.component.ts):**

```tsx
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-calculator-button',
  template: `
    <button
      [class]="buttonClass"
      (click)="handleClick()">
      {{ label }}
    </button>
  `,
  styles: [`
    button {
      padding: 15px 30px;
      font-size: 1.2rem;
      margin: 5px;
      border-radius: 8px;
      cursor: pointer;
    }
  `]
})
export class CalculatorButtonComponent {
  @Input() label: string = '';
  @Input() operation: string = '';
  @Input() buttonClass: string = 'btn-primary';

  @Output() buttonClicked = new EventEmitter<string>();

  handleClick() {
    this.buttonClicked.emit(this.operation);
  }
}
```

**Parent Component (calculator.component.ts):**

```tsx
import { Component } from '@angular/core';

@Component({
  selector: 'app-calculator',
  templateUrl: './calculator.component.html'
})
export class CalculatorComponent {
  num1: number = 0;
  num2: number = 0;
  result: number = 0;

  calculate(operation: string) {
    switch(operation) {
      case 'add':
        this.result = this.num1 + this.num2;
        break;
      case 'subtract':
        this.result = this.num1 - this.num2;
        break;
      case 'multiply':
        this.result = this.num1 * this.num2;
        break;
      case 'divide':
        this.result = this.num1 / this.num2;
        break;
    }
  }
}
```

**Parent Template (calculator.component.html):**

```html
<div class="calculator">
  <input type="number" [(ngModel)]="num1">
  <input type="number" [(ngModel)]="num2">

  <div class="operations">
    <app-calculator-button
      label="+"
      operation="add"
      (buttonClicked)="calculate($event)">
    </app-calculator-button>

    <app-calculator-button
      label="-"
      operation="subtract"
      (buttonClicked)="calculate($event)">
    </app-calculator-button>

    <app-calculator-button
      label="×"
      operation="multiply"
      (buttonClicked)="calculate($event)">
    </app-calculator-button>

    <app-calculator-button
      label="÷"
      operation="divide"
      (buttonClicked)="calculate($event)">
    </app-calculator-button>
  </div>

  <div class="result">
    Natija: {{ result }}
  </div>
</div>
```

#### Ikkinchi misol:

```tsx
// Child component
export class QuestionComponent {
  @Input() question: any;
  @Output() answerSelected = new EventEmitter<{questionId: number, answer: string}>();

  selectAnswer(answer: string) {
    this.answerSelected.emit({
      questionId: this.question.id,
      answer: answer
    });
  }
}
```

```html
<!-- Parent component -->
<app-question
  [question]="currentQuestion"
  (answerSelected)="onAnswerSelected($event)">
</app-question>
```

```tsx
// Parent component method
onAnswerSelected(data: {questionId: number, answer: string}) {
  console.log('Question:', data.questionId);
  console.log('Answer:', data.answer);
  this.checkAnswer(data.questionId, data.answer);
}
```

{% embed url="<https://youtu.be/8BUb_D6ubg8>" %}

***

#### 1.3 ViewChild va ViewChildren

`ViewChild` yordamida parent komponent child komponentning metodlari va property'lariga to'g'ridan-to'g'ri murojaat qilishi mumkin.

#### ViewChild misoli:

**Child Component (timer.component.ts):**

```tsx
import { Component } from '@angular/core';

@Component({
  selector: 'app-timer',
  template: `
    <div class="timer">
      <h3>Timer: {{ seconds }} sekund</h3>
      <p>Status: {{ isRunning ? 'Ishlayapti' : 'To\\'xtatilgan' }}</p>
    </div>
  `
})
export class TimerComponent {
  seconds: number = 0;
  isRunning: boolean = false;
  private interval: any;

  start() {
    if (!this.isRunning) {
      this.isRunning = true;
      this.interval = setInterval(() => {
        this.seconds++;
      }, 1000);
    }
  }

  stop() {
    if (this.isRunning) {
      this.isRunning = false;
      clearInterval(this.interval);
    }
  }

  reset() {
    this.stop();
    this.seconds = 0;
  }

  getTime(): number {
    return this.seconds;
  }
}

```

**Parent Component (test.component.ts):**

```tsx
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { TimerComponent } from './timer/timer.component';

@Component({
  selector: 'app-test',
  template: `
    <div class="test-container">
      <app-timer></app-timer>

      <div class="controls">
        <button (click)="startTimer()">Boshlash</button>
        <button (click)="stopTimer()">To'xtatish</button>
        <button (click)="resetTimer()">Qayta boshlash</button>
        <button (click)="showTime()">Vaqtni ko'rsatish</button>
      </div>
    </div>
  `
})
export class TestComponent implements AfterViewInit {
  @ViewChild(TimerComponent) timer!: TimerComponent;

  ngAfterViewInit() {
    // ViewChild faqat ngAfterViewInit dan keyin ishlaydi
    console.log('Timer initialized');
  }

  startTimer() {
    this.timer.start();
  }

  stopTimer() {
    this.timer.stop();
  }

  resetTimer() {
    this.timer.reset();
  }

  showTime() {
    alert(`O'tgan vaqt: ${this.timer.getTime()} sekund`);
  }
}

```

#### ViewChildren misoli (bir nechta child):

```tsx
import { Component, ViewChildren, QueryList } from '@angular/core';
import { StudentCardComponent } from './student-card/student-card.component';

@Component({
  selector: 'app-students',
  template: `
    <app-student-card *ngFor="let student of students"
                      [studentName]="student.name"
                      [score]="student.score">
    </app-student-card>

    <button (click)="highlightAll()">Hammasini belgilash</button>
  `
})
export class StudentsComponent {
  @ViewChildren(StudentCardComponent) studentCards!: QueryList<StudentCardComponent>;

  students = [
    { name: 'Ali', score: 95 },
    { name: 'Vali', score: 87 }
  ];

  highlightAll() {
    this.studentCards.forEach(card => {
      card.highlight();  // Har bir card komponentining metodini chaqirish
    });
  }
}

```

***

### 2. Service nima?

**Service** - bu Angular ilovasida ma'lumotlar bilan ishlash, biznes logika va komponentlar o'rtasida ma'lumot almashish uchun ishlatiluvchi class.

#### Service ning afzalliklari:

1. **Kodni qayta ishlatish(duplicate kodning oldini oladi)** - bir service ko'plab komponentlarda ishlatiladi
2. **Ma'lumotlarni markazlashtirish** - bir joyda saqlash
3. **Komponentlarni sodda qilish** - biznes logikani ajratish
4. **Testing qulayligi** - service'larni alohida test qilish mumkin

#### 2.1 Service yaratish

```bash
ng generate service services/math-operations
# yoki qisqasi:
ng g s services/math-operations
```

Bu quyidagi fayllarni yaratadi:

* `math-operations.service.ts`
* `math-operations.service.spec.ts` (test uchun)

**Quyidagicha service paydo bo’ladi(math-operations.service.ts):**

```tsx
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MathOperationsService {
  constructor() { }
}
```

#### 2.2 @Injectable va providedIn

`@Injectable()` decorator bu classni Dependency Injection tizimiga qo'shadi.

`providedIn: 'root'` - bu service butun ilova bo'ylab mavjud bo'ladi (singleton pattern).

**Alternativlar:**

```tsx
// 1. Root level (tavsiya etiladi)
@Injectable({
  providedIn: 'root'
})

// 2. Module level
@Injectable({
  providedIn: SomeModule
})

// 3. Component level
@Component({
  providers: [MathOperationsService]
})
```

***

#### 2.3 Service metodlarini yaratish

**math-operations.service.ts:**

```tsx
import { Injectable } from '@angular/core';

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

  constructor() { }

  // Qo'shish
  add(a: number, b: number): number {
    return a + b;
  }

  // Ayirish
  subtract(a: number, b: number): number {
    return a - b;
  }

  // Ko'paytirish
  multiply(a: number, b: number): number {
    return a * b;
  }

  // Bo'lish
  divide(a: number, b: number): number {
    if (b === 0) {
      throw new Error('Nolga bo\\'lish mumkin emas!');
    }
    return a / b;
  }

  // Faktorial
  factorial(n: number): number {
    if (n < 0) return -1;
    if (n === 0 || n === 1) return 1;

    let result = 1;
    for (let i = 2; i <= n; i++) {
      result *= i;
    }
    return result;
  }

  // Tub son tekshirish
  isPrime(num: number): boolean {
    if (num <= 1) return false;
    if (num === 2) return true;
    if (num % 2 === 0) return false;

    for (let i = 3; i <= Math.sqrt(num); i += 2) {
      if (num % i === 0) return false;
    }
    return true;
  }

  // EKUB (Eng Katta Umumiy Bo'luvchi)
  gcd(a: number, b: number): number {
    a = Math.abs(a);
    b = Math.abs(b);

    while (b !== 0) {
      const temp = b;
      b = a % b;
      a = temp;
    }
    return a;
  }

  // EKUK (Eng Kichik Umumiy Karrali)
  lcm(a: number, b: number): number {
    return Math.abs(a * b) / this.gcd(a, b);
  }

  // Fibonachchi ketma-ketligi
  fibonacci(n: number): number[] {
    if (n <= 0) return [];
    if (n === 1) return [0];

    const sequence = [0, 1];
    for (let i = 2; i < n; i++) {
      sequence.push(sequence[i - 1] + sequence[i - 2]);
    }
    return sequence;
  }

  // Darajaga oshirish
  power(base: number, exponent: number): number {
    return Math.pow(base, exponent);
  }

  // Kvadrat ildiz
  squareRoot(num: number): number {
    if (num < 0) {
      throw new Error('Manfiy sondan ildiz ololmaysiz!');
    }
    return Math.sqrt(num);
  }

  // Foizni hisoblash
  percentage(value: number, total: number): number {
    if (total === 0) return 0;
    return (value / total) * 100;
  }
}

```

***

#### 2.4 Service ni komponentda ishlatish

**calculator.component.ts:**

```tsx
import { Component } from '@angular/core';
import { MathOperationsService } from '../services/math-operations.service';

@Component({
  selector: 'app-calculator',
  templateUrl: './calculator.component.html',
  styleUrls: ['./calculator.component.css']
})
export class CalculatorComponent {
  num1: number = 0;
  num2: number = 0;
  result: number = 0;
  errorMessage: string = '';

  // Service ni constructor orqali inject qilish
  constructor(private mathService: MathOperationsService) {}

  calculate(operation: string) {
    this.errorMessage = '';

    try {
      switch(operation) {
        case 'add':
          this.result = this.mathService.add(this.num1, this.num2);
          break;
        case 'subtract':
          this.result = this.mathService.subtract(this.num1, this.num2);
          break;
        case 'multiply':
          this.result = this.mathService.multiply(this.num1, this.num2);
          break;
        case 'divide':
          this.result = this.mathService.divide(this.num1, this.num2);
          break;
        case 'gcd':
          this.result = this.mathService.gcd(this.num1, this.num2);
          break;
        case 'lcm':
          this.result = this.mathService.lcm(this.num1, this.num2);
          break;
      }
    } catch(error: any) {
      this.errorMessage = error.message;
    }
  }

  calculateFactorial() {
    this.result = this.mathService.factorial(this.num1);
  }

  checkPrime() {
    const isPrime = this.mathService.isPrime(this.num1);
    this.result = isPrime ? 1 : 0;
    alert(`${this.num1} ${isPrime ? 'tub son' : 'tub son emas'}`);
  }
}
```

***

### 3. Data Sharing with Services

Service'lar orqali ma'lumotlarni saqlash va turli komponentlar o'rtasida almashish.

#### 3.1 Oddiy ma'lumot saqlash

**student.service.ts:**

```tsx
import { Injectable } from '@angular/core';

export interface Student {
  id: number;
  name: string;
  score: number;
  grade: string;
  subject: string;
}

@Injectable({
  providedIn: 'root'
})
export class StudentService {
  private students: Student[] = [
    { id: 1, name: 'Ali Valiyev', score: 95, grade: 'A', subject: 'Matematika' },
    { id: 2, name: 'Gulnora Karimova', score: 87, grade: 'B', subject: 'Fizika' },
    { id: 3, name: 'Sardor Rahimov', score: 78, grade: 'C', subject: 'Matematika' }
  ];

  // Barcha talabalarni olish
  getAllStudents(): Student[] {
    return this.students;
  }

  // ID bo'yicha talaba topish
  getStudentById(id: number): Student | undefined {
    return this.students.find(s => s.id === id);
  }

  // Yangi talaba qo'shish
  addStudent(student: Student): void {
    this.students.push(student);
  }

  // Talabani yangilash
  updateStudent(id: number, updatedStudent: Student): void {
    const index = this.students.findIndex(s => s.id === id);
    if (index !== -1) {
      this.students[index] = updatedStudent;
    }
  }

  // Talabani o'chirish
  deleteStudent(id: number): void {
    this.students = this.students.filter(s => s.id !== id);
  }

  // Fan bo'yicha filtrlash
  getStudentsBySubject(subject: string): Student[] {
    return this.students.filter(s => s.subject === subject);
  }

  // O'rtacha ballni hisoblash
  getAverageScore(): number {
    if (this.students.length === 0) return 0;
    const total = this.students.reduce((sum, s) => sum + s.score, 0);
    return total / this.students.length;
  }

  // Eng yaxshi talaba
  getTopStudent(): Student | undefined {
    if (this.students.length === 0) return undefined;
    return this.students.reduce((top, current) =>
      current.score > top.score ? current : top
    );
  }
}

```

***

#### 4. Xulosa

Ushbu darsda siz o'rgandingiz:

#### ✅ Component Interaction:

* `@Input()` - parent → child
* `@Output()` va `EventEmitter` - child → parent
* `ViewChild` va `ViewChildren` - to'g'ridan-to'g'ri murojaat

#### ✅ Services:

* Service yaratish va ishlatish
* `@Injectable` decorator
* `providedIn: 'root'`
* Dependency Injection

#### ✅ Data Sharing:

* Oddiy property'lar

#### 5. Nazorat Savollari

1. **@Input() decorator nima uchun ishlatiladi va qanday ishlaydi?**
2. **@Output() va EventEmitter o'rtasida qanday bog'liqlik bor?**
3. **ViewChild qachon ishlatiladi va qanday cheklovlari bor?**
4. **Service nima va Angular ilovasida qanday rol o'ynaydi?**
5. **Dependency Injection pattern nima va qanday afzalliklari bor?**
6. **providedIn: 'root' va component providers o'rtasidagi farq?**
7. ~~**BehaviorSubject va oddiy o'zgaruvchi o'rtasidagi farq?**~~ (Mustaqil o'rganish uchun)
8. ~~**Observable ga subscribe qilishning qanday usullari bor?**~~(Mustaqil o'rganish uchun)
9. ~~**async pipe nima va qanday afzalliklari bor?**~~(Mustaqil o'rganish uchun)
10. ~~**Service'da BehaviorSubject ishlatishning afzalliklari nimada?**~~(Mustaqil o'rganish uchun)

#### 6. Amaliy Topshiriq

**Student CRUD System**

**Maqsad:** To'liq CRUD (Create, Read, Update, Delete) tizimi yaratish.

**Talablar:**

1. `StudentService` yarating:
   * `Student[]` massivini ishlatish
   * CRUD metodlari: add, update, delete, getAll
   * Filtrlash: fan, baho bo'yicha
   * Statistika: o'rtacha ball, eng yaxshi talaba
2. **StudentListComponent** (Parent):
   * Barcha talabalarni ko'rsatish
   * Qidiruv va filtrlash
   * Yangi talaba qo'shish tugmasi
3. **StudentCardComponent** (Child):
   * @Input(): student ma'lumotlari
   * @Output(): edit, delete hodisalari
   * ViewChild: expand/collapse detalls
4. **StudentFormComponent**:
   * Talaba qo'shish/tahrirlash formasi
   * Validatsiya (ism, ball, fan)
   * @Output(): save hodisasi

**Bosqichlar:**

```bash
# 1. Service yaratish
ng g s services/student

# 2. Komponentlar yaratish
ng g c components/student-list
ng g c components/student-card
ng g c components/student-form
```

#### Test

[QuizBot](https://t.me/QuizBot?start=BI5tHB0y)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://odilbeks-organization.gitbook.io/angular-ustoz-shogirt/componentlararo-malumot-almashish.-servicega-kirish.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
