Angular में Expression has changed after it was checked एरर को कैसे ठीक करें

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

«Expression has changed after it was checked» — यह क्यों होता है और इससे कैसे निपटें?

\n\n

अगर आपने कभी Angular में एप्लिकेशन बनाया है, तो आपने शायद कंसोल में यह डरावना मैसेज देखा होगा:

\n\n
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.
\n\n

यह एरर डेवलपर्स के लिए एक बड़ी समस्या है। Stack Overflow पर हज़ारों सवाल, घंटों डिबगिंग, और कई नर्वस ब्रेकडाउन। लेकिन अच्छी खबर यह है कि इसे न सिर्फ ठीक किया जा सकता है, बल्कि समझा भी जा सकता है कि यह क्यों होता है। इस आर्टिकल में हम Expression has changed after it was checked एरर के मुख्य कारणों को समझेंगे, TypeScript में उदाहरण लिखेंगे और ठोस समाधान देंगे। चलिए शुरू करते हैं!

\n\n

यह एरर आखिर क्या है?

\n\n

Angular दो मोड में काम करता है: डेवलपमेंट (dev mode) और प्रोडक्शन। Dev मोड में फ्रेमवर्क एक अतिरिक्त जांच करता है — हर चेंज डिटेक्शन साइकल के बाद, वह दूसरा पास चलाता है ताकि यह सुनिश्चित कर सके कि डेटा "चलते-फिरते" नहीं बदला। अगर पहले और दूसरे पास के बीच वैल्यू बदल जाती है — तो Angular ExpressionChangedAfterItHasBeenCheckedError के साथ क्रैश हो जाता है।

\n\n

सीधे शब्दों में: आपने Angular को बताया "यह है डेटा", उसने इसे चेक किया, और फिर आपने इसे बदल दिया। Angular नाराज हो जाता है और चिल्लाता है।

\n\n

एरर के 3 मुख्य कारण

\n\n

1. ngAfterViewInit के बाद लाइफसाइकल हुक्स में डेटा बदलना

\n\n

सबसे आम कारण — ngAfterViewInit, ngAfterContentInit या ngAfterViewChecked हुक में कंपोनेंट की प्रॉपर्टी बदलने की कोशिश करना। इस समय Angular व्यू की जांच पूरी कर चुका होता है, और कोई भी बदलाव एरर का कारण बनता है।

\n\n

TypeScript में उदाहरण:

\n\n
import { Component, AfterViewInit } from '@angular/core';\n\n@Component({\n  selector: 'app-example',\n  template: '<p>{{ message }}</p>'\n})\nexport class ExampleComponent implements AfterViewInit {\n  message = 'शुरुआती वैल्यू';\n\n  ngAfterViewInit(): void {\n    // एरर! व्यू चेक करने के बाद प्रॉपर्टी बदल रहे हैं\n    this.message = 'बदली हुई वैल्यू';\n  }\n}
\n\n

यहाँ Angular पहले message को चेक करता है (वैल्यू "शुरुआती वैल्यू"), फिर ngAfterViewInit को कॉल करता है, जहाँ आप इसे "बदली हुई वैल्यू" में बदल देते हैं। दोबारा चेक करने पर Angular को अंतर दिखता है और वह एरर फेंकता है।

\n\n

2. लाइफसाइकल के अंदर एसिंक्रोनस ऑपरेशन

\n\n

अगर आप हुक के अंदर एसिंक्रोनस कोड (setTimeout, Promise, Observable) चलाते हैं, तो डेटा अपडेट Angular के कंट्रोल ज़ोन के बाहर होता है।

\n\n

उदाहरण:

\n\n
import { Component, OnInit } from '@angular/core';\n\n@Component({\n  selector: 'app-async',\n  template: '<p>{{ data }}</p>'\n})\nexport class AsyncComponent implements OnInit {\n  data = 'शुरू';\n\n  ngOnInit(): void {\n    setTimeout(() => {\n      this.data = 'नई वैल्यू';\n    }, 0);\n  }\n}
\n\n

हालाँकि setTimeout 0 मिलीसेकंड की देरी से लगभग तुरंत चलता है, Angular पहले ही अपनी जांच पूरी कर चुका होता है। Dev मोड में यह एरर का कारण बनेगा।

\n\n

3. नेस्टेड कंपोनेंट और Input के ज़रिए डेटा ट्रांसफर

\n\n

जब पैरेंट कंपोनेंट चाइल्ड कंपोनेंट को @Input के ज़रिए डेटा भेजता है, और चाइल्ड कंपोनेंट अपने लाइफसाइकल में इस डेटा को बदलने की कोशिश करता है, तो कंफ्लिक्ट होता है।

\n\n

उदाहरण:

\n\n
// पैरेंट कंपोनेंट\n@Component({\n  selector: 'app-parent',\n  template: '<app-child [value]="parentValue"></app-child>'\n})\nexport class ParentComponent {\n  parentValue = 'मूल वैल्यू';\n}\n\n// चाइल्ड कंपोनेंट\n@Component({\n  selector: 'app-child',\n  template: '<p>{{ value }}</p>'\n})\nexport class ChildComponent implements AfterViewInit {\n  @Input() value: string = '';\n\n  ngAfterViewInit(): void {\n    this.value = 'चाइल्ड में बदला गया'; // यह एरर देगा\n  }\n}

ब्लॉग

पुस्तक अनुशंसाएँ