موارد Angular ليست مناسبة للاستخدام في الـ Guards

قدم إصدار Angular 22 واجهة برمجة تطبيقات Resource API المستقرة. تساعدك هذه الأداة في الاستعلام عن واجهات برمجة التطبيقات (APIs) وتتبع حالات التحميل أو الخطأ. وهي تعمل بشكل جيد في العديد من المهام.

ومع ذلك، لا تستخدمها في الـ Guards أو الـ Resolvers.

تقوم الـ Guards والـ Resolvers بحظر التنقل. يتحقق الـ Guard مما إذا كان بإمكان المستخدم الوصول إلى مسار معين، بينما يقوم الـ Resolver بجلب البيانات قبل تحميل المكون (component). يتطلب كلاهما قيمة boolean أو Promise أو Observable لإنهاء منطقه البرمجي.

تنتمي الـ Resources إلى Signals API. الـ Signals هي عناصر تفاعلية (reactive)، ولا تُرجع القيم بشكل متزامن (synchronously). عندما تنشئ Resource، تبدأ القيمة كـ undefined، ثم تنتقل إلى حالة التحميل (loading state).

انظر إلى هذا الخطأ:

export const authGuard: CanActivateFn = () => {
  const authResource = httpResource<boolean>(() => ({
    url: '/api/auth/status',
  }));

  return authResource.value() ?? false;
};

تُرجع طريقة .value() قيمة الـ signal الحالية فوراً. وبما أن استدعاء الـ API يستغرق وقتاً، فإن القيمة تكون undefined في البداية. يرى الـ Guard أن القيمة undefined، فيتعامل معها على أنها false، ويقوم بإلغاء عملية التنقل. وبالتالي، لا ينتظر التطبيق استجابة الـ API أبداً.

لإصلاح ذلك، يجب عليك تحويل الـ Resource إلى Observable، وهذا يضيف تعقيداً غير ضروري.

يجب أن تمثل الـ Guards حدثاً غير متزامن (asynchronous) واحداً. ولتحقيق ذلك، استخدم HttpClient مع Observables أو native fetch API مع Promises.

الطريقة الصحيحة:

export const authGuard: CanActivateFn = () => {
  const http = inject(HttpClient);

  return http.get<boolean>('/api/auth/status');
};

يخبر الـ Observable الـ Router بالانتظار حتى يكتمل الطلب.

استخدم Resource API للمكونات (components) والخدمات (services)؛ فهي رائعة لربط البيانات غير المتزامنة بقوالبك (templates). أما الـ Promises والـ Observables، فاجعلها لمنطق الـ Router الخاص بك.

المصدر: https://dev.to/geromegrignon/angular-resources-are-not-a-good-fit-for-guards-58j