Unable to get property 'remove' of undefined or null reference - reactjs

According to my client-side error logs, my ReactJS app is sometimes throwing the following exception.
TypeError: Unable to get property 'remove' of undefined or null reference
at M.willDeleteListener (eval code:17:25544)
at v.deleteAllListeners (eval code:1:25843)
at m.Mixin.unmountComponent (eval code:16:15442)
at i.unmountComponent (eval code:15:5262)
at unmountChildren (eval code:17:3368)
at _.Mixin.unmountChildren (eval code:17:2153)
at m.Mixin.unmountComponent (eval code:16:15442)
at i.unmountComponent (eval code:15:5262)
at _.unmountComponent (eval code:15:16416)
at i.unmountComponent (eval code:15:5262)
I think the source of the error is in https://github.com/facebook/react/blob/35962a00084382b49d1f9e3bd36612925f360e5b/src/renderers/dom/client/eventPlugins/SimpleEventPlugin.js#L600
I've been unable to reproduce (either locally or in production).
What could be causing this problem to happen? I need some ideas of things to try that could reproduce the error.

I came acrossed above error "Unable to get property 'remove' of undefined or null reference" in IE11 for angular 6 application. I was using NgClass directive to set the CSS class dynamically for SVG elements.
<svg viewBox="0 0 145 110" width="145" height="110" id="svg1">
<path class="bg" [ngClass]="{'my-class': my-cond = 'condition'}" stroke="#ccc" />
</svg>
Solution: IE10 and IE11 requires the following npm, for NgClass to support on SVG elements.
- Run > npm install --save classlist.js
- import 'classlist.js'; // In polyfills.js

I've gotten this error a few times now, and it seems to happen when I'm accessing a property that doesn't yet exist in the render function. My application is using React/Redux and ImmmutableJS, and there are many AJAX calls that happen on mount of any given component, so I've got to be sure that I'm breaking out of the render function until everything is finished loading. For example, I get the error in question when I have this:
render () {
const displayName = this.props.myObject.get('displayName')
if (this.props.loading) return <Loading />
return <div>{displayName}</div>
}
But not when I switch around the loading check:
render () {
if (this.props.loading) return <Loading />
const displayName = this.props.myObject.get('displayName')
return <div>{displayName}</div>
}
Checking for existence of the object also works to get rid of this pesky error.

Piggybacking on #LaurelB's response, I diagnosed this to happen on React elements when I toggle the function of an event bind (say onClick) based on some variable whose value changes. I realized this might not be good practice, after all.

Related

How do I set the value of p-checkbox programmatically

The following code does not produce a error but nothing happens. I'm using ng v11, reactive forms, and primeng 11. What am I missing?
<p-checkbox label="Confirm"
formControlName="chkConfirm">
</p-checkbox>
typescript:
this.chkConfirm?.setValue(true);
edit:
Adding error message found in console:
ERROR TypeError: this.model.indexOf is not a function
at Checkbox.isChecked (primeng-checkbox.js:78)
at Checkbox.writeValue (primeng-checkbox.js:101)
at setUpControl (forms.js:2379)
at FormGroupDirective.addControl (forms.js:5710)
at FormControlName._setUpControl (forms.js:6285)
at FormControlName.ngOnChanges (forms.js:6230)
at FormControlName.rememberChangeHistoryAndInvokeOnChangesHook (core.js:1498)
at callHook (core.js:2517)
at callHooks (core.js:2484)
at executeInitAndCheckHooks (core.js:2435)

"TypeError: Cannot read property 'pseudoType' of undefined" with chrome-devtools

I'm developing an electron app with React for the front-end. I get the following error in my console when I run my app and hit refresh. My app works as expected, but it's kind of annoying to see this error pop up in my console and not know what it means. Any ideas?
This is the error message I get in my console:
[1] [36084:0511/083524.886880:ERROR:CONSOLE(972)] "TypeError: Cannot read property 'pseudoType' of undefined TypeError: Cannot read property 'pseudoType' of undefined
[1] at SDK.DOMNode._removeChild (chrome-devtools://devtools/bundled/shell.js:4301:28)
[1] at SDK.DOMModel._childNodeRemoved (chrome-devtools://devtools/bundled/shell.js:4420:121)
[1] at SDK.DOMDispatcher.childNodeRemoved (chrome-devtools://devtools/bundled/shell.js:4464:54)
[1] at Protocol.InspectorBackend._DispatcherPrototype.dispatch (chrome-devtools://devtools/bundled/shell.js:3399:26)
[1] at Protocol.SessionRouter._onMessage (chrome-devtools://devtools/bundled/shell.js:3355:41)
[1] at SDK.MainConnection._dispatchMessage (chrome-devtools://devtools/bundled/shell.js:3486:17)
[1] at Common.Object.dispatchEventToListeners (chrome-devtools://devtools/bundled/shell.js:494:23)
[1] at innerDispatch (chrome-devtools://devtools/bundled/shell.js:972:98)
[1] at Host.InspectorFrontendAPIImpl._dispatch (chrome-devtools://devtools/bundled/shell.js:972:1)
[1] at DevToolsAPIImpl._dispatchOnInspectorFrontendAPI (chrome-devtools://devtools/bundled/devtools_compatibility.js:57:36)", source: chrome-devtools://devtools/bundled/shell.js (972)
I've isolated the error to this snippet of code below. If I comment it out, I don't get the error. I couldn't find the cause of the error by reading the BrowserWindow docs.
BrowserWindow.addDevToolsExtension(
path.join(
os.homedir(),
"/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/3.6.0_0"
)
);
BrowserWindow.addDevToolsExtension(
path.join(
os.homedir(),
"/Library/Application Support/Google/Chrome/Default/Extensions/lmhkpmbekcpmknklioeibfkpmmfibljd/2.17.0_0"
)
);
mainWindow.webContents.openDevTools();
I think that the problems here could be of two different types: the path is incorrect, there is already a path that exists as the one you passed as a parameter or you are calling this function before that the module app is on its ready state.
To solve the first problem i would test the path that os.homedir() gives you back in a different part of the code to see what ends up to be at the time that you join it with the path indicated
in the function join; "/Library/Application/Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/3.6.0_0".
To solve the second problem i would refactor the code to call the function in the appropriate lifecycle point to be sure that the app module is on the ready state.

Can't check if array is initialized or empty with ngIf

I have a property on my component for alert messages that may get populated:
alerts: ReportAlertMessage[];
I am trying to us ngIf to display an output if the array has any data.
I first tried:
<div class="row" *ngIf="alerts">
But it didn't work, it returns this error:
Cannot read property 'nativeElement' of undefined
So I tried:
<div class="row" *ngIf="typeof(alerts) !== 'undefined'">
and this gives me:
self.context.typeof is not a function
I want to check that it is initialized and has at least 1 value. What is the way to do this with ngIf?
edit:
full exception message. Problem seems to be ocurring because I am populating the array with an observable:
EXCEPTION: Uncaught (in promise): Error: Error in :0:0 caused by: Cannot read property 'nativeElement' of undefined
Error: Error in :0:0 caused by: Cannot read property 'nativeElement' of undefined
at ViewWrappedError.ZoneAwareError (http://localhost:4200/polyfills.bundle.js:3561:33)
at ViewWrappedError.BaseError [as constructor] (http://localhost:4200/vendor.bundle.js:30581:16)
at ViewWrappedError.WrappedError [as constructor] (http://localhost:4200/vendor.bundle.js:30646:16)
at new ViewWrappedError (http://localhost:4200/vendor.bundle.js:61302:16)
at CompiledTemplate.proxyViewClass.DebugAppView._rethrowWithContext (http://localhost:4200/vendor.bundle.js:83662:23)
at CompiledTemplate.proxyViewClass.DebugAppView.detectChanges (http://localhost:4200/vendor.bundle.js:83635:18)
at ViewRef_.detectChanges (http://localhost:4200/vendor.bundle.js:62229:20)
at RouterOutlet.activate (http://localhost:4200/vendor.bundle.js:67737:42)
at ActivateRoutes.placeComponentIntoOutlet (http://localhost:4200/vendor.bundle.js:25393:16)
at ActivateRoutes.activateRoutes (http://localhost:4200/vendor.bundle.js:25360:26)
at http://localhost:4200/vendor.bundle.js:25296:58
at Array.forEach (native)
at ActivateRoutes.activateChildRoutes (http://localhost:4200/vendor.bundle.js:25296:29)
at ActivateRoutes.activate (http://localhost:4200/vendor.bundle.js:25270:14)
at http://localhost:4200/vendor.bundle.js:24830:22
I have also tried writing a static bool. It appears that this error occurs when I set the value of a property inside the callback from an observable
Alternatively you can call a method in your component as
<div class="row" *ngIf="isEmpty(alerts)">
Component function
isEmpty(alerts){
if(alerts===[]) {
return true;
} else {
return false;
}
}
Seems the first is the correct way to do it. It the alerts access modifier public
Try this
<div class="row" *ngIf="alerts.length">

Unexpected end of input in ui-bootstrap file

I get this error whenever I load the page I am building. Everything worked fine until I copied the angular-ui-bootstrap js file. I have not changed anything from the file.
angular.module('ui.bootstrap.datepicker').run(function() {
!angular.$$csp().noInlineStyle && angular.element(document).find('head').prepend('<style type="text/css">.uib- datepicker .uib-title{width:100%;}.uib-day button,.uib-month button,.uib-year button{min-width:100%;}.uib-datepicker-popup.dropdown-menu{display:block;}.uib-button-bar{padding:10px 9px 2px;}</style>');});
This is the portion of code where it has a missing } but that is not the case as I can see. I am running AngularJS 1.4.9 and Bootstrap 3.3.2.
Any ideas?
update: When I change to Angular 1.4.0 I get
$q.resolve is not a function error
full error
TypeError: $q.resolve is not a function
at http://localhost:8080/build/js/all-136a0f7ece.js:46792:32
at Object.forEach (http://localhost:8080/build/js/all-136a0f7ece.js:350:20)
at Object.resolve (http://localhost:8080/build/js/all-136a0f7ece.js:46790:19)
at Object.$modal.open (http://localhost:8080/build/js/all-136a0f7ece.js:47357:69)
at Scope.$scope.open (http://localhost:8080/build/js/all-136a0f7ece.js:46443:35)
at fn (eval at <anonymous> (http://localhost:8080/build/js/all-136a0f7ece.js:13036:15), <anonymous>:4:203)
at callback (http://localhost:8080/build/js/all-136a0f7ece.js:23090:17)
at Scope.$eval (http://localhost:8080/build/js/all-136a0f7ece.js:15719:28)
at Scope.$apply (http://localhost:8080/build/js/all-136a0f7ece.js:15818:23)
at HTMLAnchorElement.<anonymous> (http://localhost:8080/build/js/all-136a0f7ece.js:23095:23)

Getting error: Error while waiting for Protractor to sync with the page: {}

My e2e.conf.coffee file is:
exports.config =
baseUrl: 'http://localhost:9001'
specs: [
'e2e/**/*.coffee'
]
framework: 'jasmine'
I have my node project running and listening on port 9001.
My test is:
describe 'Happy Path', ->
it 'should show the login page', ->
console.log browser
expect(browser.getLocationAbsUrl()).toMatch("/view1");
it 'should fail to login', ->
setTimeout ->
console.log "FAIL!"
, 1200
And the error that I get is:
Failures:
1) Happy Path should show the login page
Message:
Error: Error while waiting for Protractor to sync with the page: {}
Stacktrace:
Error: Error while waiting for Protractor to sync with the page: {}
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
==== async task ====
WebDriver.executeScript()
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
==== async task ====
Asynchronous test function: it("should show the login page")
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>
at <anonymous>==== async task ====
What am I doing wrong??
The (very) short version: use browser.driver.get instead of browser.get.
The longer version: Protractor is basically a wrapper around Selenium and its Javascript WebDriver code. Protractor adds code to wait for Angular to "settle down" (i.e., finish going through its $digest loops) before proceeding with your test code. However, if your page doesn't have Angular on it, then Protractor will wait "forever" (actually just until it times out) waiting for Angular to settle.
The browser object that Protractor exposes to your test is an instance of Protractor (i.e., if you see old answers on Stack Overflow with var ptor = protractor.getInstance(); ptor.doSomething(), then you can replace ptor with browser in those old answers). Protractor also exposes the wrapped Selenium WebDriver API as browser.driver. So if you call browser.get, you're using Protractor (and it will wait for Angular to settle down), but if you call browser.driver.get, you're using Selenium (which does not know about Angular).
Most of the time, you'll be testing Angular pages, so you'll want to use browser.get to get the benefits of Protractor. But if your login page doesn't use Angular at all, then you should be using browser.driver.get instead of browser.get in the tests that test your login page. Do note that you'll also need to use the Selenium API rather than the Protractor API in the rest of the test: for example, if you have an HTML input element with id="username" somewhere in your page, you'll want to access it with browser.driver.findElement(by.id('username')) instead of element(by.model('username')).
For more examples, see this example from the Protractor test suite (or try this link if the previous one ever goes away). See also the Protractor docs which state:
Protractor will fail when it cannot find the Angular library on a page. If your test needs to interact with a non-angular page, access the webdriver instance directly with browser.driver.
Example code: In your login test above, you would want to do something like:
describe 'Logging in', ->
it 'should show the login page', ->
browser.driver.get "http://my.site/login.html"
// Wait for a specific element to appear before moving on
browser.driver.wait ->
browser.driver.isElementPresent(by.id("username"))
, 1200
expect(browser.driver.getCurrentUrl()).toMatch("/login.html");
it 'should login', ->
// We're still on the login page after running the previous test
browser.driver.findElement(by.id("username")).sendKeys("some_username")
browser.driver.findElement(by.id("password")).sendKeys("some_password")
browser.driver.findElement(by.xpath('//input[#type="submit"]')).click()
(A note of caution: I haven't done much CoffeeScript, and it's entirely possible I made a CoffeeScript syntax error in the code above. You may want to check its syntax before blindly copying and pasting it. I am, however, confident in the logic, because that's copied and pasted almost verbatim from my Javascript code that tests a non-Angular login page.)
If you need to be using browser.get and are getting this error,
the issue is most likely to be the rootElement property in protractor config file.
By default Protractor assumes that the ng-app declaration sits on the BODY-element. However, in our case, it could be declared somewhere else in the DOM. So we have to assign the selector of that element to the rootElement property:
// rootElement: 'body', // default, but does not work in my case
rootElement: '.my-app', // or whatever selector the ng-app element has
Corresponding HTML:
<div ng-app="myApp" class="my-app">
I copied the answer from http://www.tomgreuter.nl/tech/2014/03/timing-errors-with-angular-protractor-testing/
I got this error, too, but in my case my tests were working and this error occured after expanding them.
Turns out that this error may occur, if you try to call getText() in your describe block instead of your testcases. My Set-Up was like following:
describe('Test Edit Functionality', function() {
var testEntry = $$('.list-entry').first(),
testEntryOldName = testEntry.getText();
it('Should keep old name if edit is aborted', [...]);
});
That caused the Error Error while waiting for Protractor to sync with the page: {}.
I fixed it by moving the assigment into a beforeEach-block
describe('Test Delete Functionality', function() {
var testEntry = $$('.list-entry').first(),
testEntryOldName;
beforeEach(function() {
testEntryOldName = testEntry.getText();
});
});
Or, may be better, assign it in the specific testcases you need this value (if you dont need it in all).
Not sure where I picked up the pieces that put this answer at this point, but this is what works for me:
Add class='ng-app' to the element that contains your app.
<div ng-app="myApp" ng-controller="myController" class="ng-app"></div>
Add rootElement to your protractor.conf.
exports.config = {
specs: ['your-spec.js'],
rootElement: ".ng-app"
};
Use browser.driver.get not browser.get.
describe('foobar element', function() {
it('should be "baz" after view is initialized', function() {
browser.driver.get('http://localhost/view');
var inputBox = $('input[name=foobar]');
expect(inputBox.getAttribute('value')).toEqual("baz");
});
});
I got this issue a couple of days back on my CT. My tests were running fine until 3 days back, but then this protractor sync error showed up and just won't go away with any of the solutions/hacks provided here and at https://github.com/angular/protractor/issues/2643.
I checked that this issue only occurred in Firefox headless and worked fine with Chrome headless. Upgrading from Firefox v69 to the latest(v72 currently) fixed the issue. I do not know why the issue started manifesting itself and how it got fixed with the upgrade, but for what it is worth I thought this information might come in handy for someone else.

Resources