«No provider for HttpClient» — خطأ يزعج الجميع
\n\nأنت تكتب خدمة في Angular، وتقوم بتوصيل HttpClient في المُنشئ، وتشغيل التطبيق... وفجأة! تتحول وحدة تحكم المتصفح إلى اللون الأحمر: NullInjectorError: No provider for HttpClient. هل هذا مألوف؟
هذا الخطأ هو بمثابة «طقوس العبور» الحقيقية لكل مطور Angular. تمت مناقشته أكثر من 400 ألف مرة على Stack Overflow، وفي عام 2025 لا يزال يجمع المبتدئين والمحترفين. لكن الخبر السار: هناك حل، وليس حلاً واحداً فقط.
\n\nفي هذه المقالة، سنستعرض 5 أفضل الممارسات للتغلب على No provider for HttpClient في Angular 18+ و TypeScript. هيا بنا!
لماذا يحدث خطأ «No provider for HttpClient» أصلاً؟
\n\nجوهر الخطأ بسيط: Angular لا يعرف كيفية إنشاء مثيل لـ HttpClient. في Angular، يتم استخدام حقن التبعية (DI) — وهي حاوية تدير إنشاء الكائنات. إذا طلبت HttpClient، ولم يكن لدى حاوية DI وصفة لبنائه — يظهر الخطأ.
الموقف الكلاسيكي:
\n\nimport { Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\n\n@Injectable({ providedIn: 'root' })\nexport class DataService {\n constructor(private http: HttpClient) {} // ❌ خطأ: No provider for HttpClient\n}\n\n\nيقول Angular: «أرى أنك تريد HttpClient، لكنني لا أعرف من أين أحصل عليه». وهذا منطقي — لقد نسينا استيراد الوحدة النمطية أو المزوّد الذي يسجل HttpClient في حاوية DI.
أفضل الممارسات لعام 2025: 5 طرق لإصلاح الخطأ
\n\n1. الطريقة الكلاسيكية: HttpClientModule (Angular حتى الإصدار 18)
\n\nالطريقة الأقدم والأكثر اختباراً — استيراد HttpClientModule في الوحدة النمطية الجذرية للتطبيق.
// app.module.ts\nimport { NgModule } from '@angular/core';\nimport { BrowserModule } from '@angular/platform-browser';\nimport { HttpClientModule } from '@angular/common/http';\nimport { AppComponent } from './app.component';\n\n@NgModule({\n declarations: [AppComponent],\n imports: [\n BrowserModule,\n HttpClientModule // ✅ ها هو المنقذ\n ],\n providers: [],\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\n\n\nتعمل هذه الطريقة في Angular 2–17. في عام 2025، لا تزال صالحة إذا كنت تستخدم بنية NgModule-based. العيب: تضيف وحدة HttpClient بأكملها، حتى لو كنت تحتاج فقط إلى الوظائف الأساسية.
\n\n2. المعيار الحديث: provideHttpClient() (Angular 15+)
\n\nمع ظهور المكونات المستقلة (standalone components)، انتقل Angular إلى المزوّدات الوظيفية. الآن بدلاً من الوحدة النمطية، تستخدم الدالة provideHttpClient.
// main.ts (standalone bootstrap)\nimport { bootstrapApplication } from '@angular/platform-browser';\nimport { provideHttpClient } from '@angular/common/http';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, {\n providers: [\n provideHttpClient() // ✅ تسجيل HttpClient\n ]\n}).catch(err => console.error(err));\n\n\nهذه هي الطريقة الموصى بها في Angular 18+ وعام 2025. إنها أخف وزناً وأسرع ولا تجلب كوداً زائداً. إذا كنت تكتب تطبيقاً جديداً — استخدمها.
\n\n3. الطريقة المتقدمة: provideHttpClient() مع withFetch()
\n\nبدءاً من Angular 17، أصبح من الممكن استخدام واجهة برمجة تطبيقات fetch بدلاً من XMLHttpRequest. وهذا يعطي زيادة في الأداء ودعماً للميزات الحديثة (مثل البث).
\n\nimport { bootstrapApplication } from '@angular/platform-browser';\nimport { provideHttpClient, withFetch } from '@angular/common/http';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, {\n providers: [\n provideHttpClient(\n