I am trying to test my angular 4.1.0 component —
export class CellComponent implements OnInit {
lines: Observable<Array<ILine>>;
@Input() dep: string;
@Input() embedded: boolean;
@Input() dashboard: boolean;
constructor(
public dataService: CellService,
private route: ActivatedRoute,
private router: Router, private store: Store<AppStore>) {
}
}
However, a simple «should create» test throws this cryptic error…
NetworkError: Failed to execute ‘send’ on ‘XMLHttpRequest’: Failed to load ‘ng:///DynamicTestModule/module.ngfactory.js’.
so I found this question, which suggests that the issue is the component has @Input)_
params which aren’t set, however, if I modify my test like so:
it('should create', inject([CellComponent], (cmp: CellComponent) => {
cmp.dep = '';
cmp.embedded = false;
cmp.dashboard = false;
expect(cmp).toBeTruthy();
}));
then I still get the same issue, similarly, if I remove the @Input()
annotations from the component, still no difference. How can I get these tests to pass?
Splaktar
5,0565 gold badges42 silver badges74 bronze badges
asked Jul 30, 2017 at 10:57
George EdwardsGeorge Edwards
8,88919 gold badges76 silver badges156 bronze badges
3
This is a problem of the new Angular Cli. Run your test with --sourcemaps=false
and you will get the right error messages.
See details here: https://github.com/angular/angular-cli/issues/7296
EDIT:
Shorthand for this is:
ng test -sm=false
As of angular 6 the command is:
ng test --source-map=false
answered Aug 9, 2017 at 12:51
7
I had the same issue using angualar cli 6, I have used this tag to get the right error message :
ng test --source-map=false
Maybe it will help someone .
answered Jun 6, 2018 at 21:42
jmuhirejmuhire
1,95220 silver badges19 bronze badges
For my case there was a mock data problem and in case of Array
, I was returning string
from the mock.
someApi = fixture.debugElement.injector.get(SomeApi);
spyOn(someApi, 'someMethod')
.and.returnValue(Observable.of('this is not a string but array'));
The error message is really distracting and was not telling the actual error. Running
ng test --source=false
pointed the correct error and line, and helped me to fix it quickly.
Many time it happens when you mock data is incomplete or incorrect.
answered Oct 16, 2017 at 20:38
Aniruddha DasAniruddha Das
19.6k20 gold badges96 silver badges131 bronze badges
0
You can either set input() property to default value in component.ts
@Input() tableColumns: Array<any> = [];
@Input() pageObj: any = '';
OR
Modify your component.spec.ts file in following way,
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
component.tableColumns = [];
component.pageObj = '';
fixture.detectChanges();
});
answered Jun 14, 2018 at 11:02
Mangesh DaundkarMangesh Daundkar
1,0281 gold badge13 silver badges20 bronze badges
As suggested above here: https://stackoverflow.com/a/45570571/7085047 my problem was in my ngOnInit
. I was calling a mock swagger-generated REST controller proxy. It was returning null, and I was subscribing to that null, which doesn’t work…
The error came back:
Failed to load ng:///DynamicTestModule/MockNodeDashboardComponent_Host.ngfactory.js: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
I fixed the issue using ts-mockito: https://github.com/NagRock/ts-mockito
I added code to create a mock instance like this:
import { mock, instance, when } from 'ts-mockito';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { MockScenario } from './vcmts-api-client/model/MockScenario';
const MockVcmtsnodemockresourceApi: VcmtsnodemockresourceApi = mock(VcmtsnodemockresourceApi);
const obs = Observable.create((observer: Observer<MockScenario[]>) => {
observer.next(new Array<MockScenario>());
observer.complete();
});
when(MockVcmtsnodemockresourceApi.getMockScenariosUsingGET()).thenReturn(obs);
const instanceMockVcmtsnodemockresourceApi: VcmtsnodemockresourceApi = instance(MockVcmtsnodemockresourceApi);
And then added the instance to the test’s providers array like this:
beforeEach(async(() => {
TestBed.configureTestingModule({
...
providers: [
...
{ provide: VcmtsnodemockresourceApi, useValue: instanceMockVcmtsnodemockresourceApi },
...
]
}).compileComponents();
}));
answered Nov 1, 2017 at 14:52
Datum GeekDatum Geek
1,16014 silver badges20 bronze badges
2
I faced the same issue and I’ve found out that to fix it you have to set your inputs for the component in the method beforeEach as shown below:
beforeEach(() => {
fixture = TestBed.createComponent(CellComponent );
cmp = fixture.debugElement.componentInstance;
cmp.dep = '';
cmp.embedded = false;
cmp.dashboard = false;
fixture.detectChanges();
});
This will definitely resolve your issue.
answered Sep 6, 2018 at 6:48
Jayant PatilJayant Patil
1,4822 gold badges10 silver badges18 bronze badges
This can be related to Chrome hiding an actual test error. The test area will be confusing some mock http factory that it can’t load and therefore that is the error it will report. Most likely the error will be around the ngOnInit area where an object is, say, expecting sub objects and they are not defined.
To try and get to the bottom of the error, switch to PhantomJS temporarily which seems to suffer less from these initialisation errors and this will hopefully report the actual error to you. Several occasions I found to be where an object expected on initialisation wasn’t complete.
IE:
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
component.object = {}
// should be:
component.object = {"innerObjectThatIsNeeded" : []}
Correcting the object allowed PhantomJS to complete and also Chrome to move on to the next test.
Other than that I’ve not seen a solution to remove the issue from Chrome. As ever try and adopt a «remove the code, until error goes» policy to chase down the error.
UPDATE: Note this is now a quite an old answer, I wouldn’t recommend using PhantomJS anymore (EOL). Browser test reporting has got a lot better and if Chrome is giving you grief then try Firefox, which also runs tests really well nowadays.
answered Aug 8, 2017 at 14:06
PeterSPeterS
2,75823 silver badges35 bronze badges
I also had this error, which truth be told is fairly non talkative.
It was related to the HTTP calls trough my services
I use myService.ts with 2 methods
get();
getAll();
I am mocking this service : mockMyService.ts
The error was here because my component was using getAll() method that I forgot to implement in the mockMyService, so I just added the method :
private mockObjects = [
{
'id': '1',
'champ1': 'TECH',
'champ2': 2,
'champ3': 'Data bidon'
},
{
'id': '2',
'champ1': 'TECH',
'champ2': 2,
'champ3': 'Data au pif'
},
{
'id': '3',
'champ1': 'FUNC',
'champ2': 3,
'champ3': 'Data quelconque'
},
];
getAll(): Observable<any> {
return Observable.of(this.mockObjects);
}
Error was gone
answered Jan 9, 2018 at 8:53
DeunzDeunz
1,70919 silver badges30 bronze badges
In my case the culprit was observable.timeout(x).retry(y)
applied somewhere on the returned Observable on the service class level, then again in the component which was using that service.
Everything worked correctly in the browser up until angular-cli 1.4. Then started failing during Karma tests (with such a silly error). The solution was of course to tidy up these timeout/retry operators.
answered Aug 23, 2017 at 14:13
Marcin RMarcin R
1,5111 gold badge9 silver badges6 bronze badges
0
For me this message appear when a mock is falsy in my tests : usually you provide mockService in your tests bootstrap. If your mock is incomplete or falsy, then angular return this stupid error.
More information on my case here
answered Aug 9, 2017 at 15:07
RebolonRebolon
1,2579 silver badges29 bronze badges
What I would be doing is:
Add console.log() s, line after line in ngOnint() and find out how far it goes , then inspect the line which it wont pass through.
Ex:
ngOnInit() {
this.route.paramMap
.switchMap(params => {
this.busy = true;
this.updateErrors(null);
console.log(params);
**const id = params.get('id');**
console.log(id);
if (id === 'new') {
this.editMode = true;
return Observable.of(GroupComponent.newGroup());
}
return this.apiService.getGroup(id);
})
}
This was failing on my test with the same error in this post. As shown above, I had two console.logs. First one passed thorugh , but the second one not. So I realized the issue is on line const id = params.get(‘id’); and I fixed it.
Hope this will help someone.
answered Jan 9, 2018 at 21:13
JosfJosf
7581 gold badge8 silver badges21 bronze badges
@redroot — Thanks for looking into this. There are a few different types of request involved here, so I don’t think what you’re seeing is necessarily related to what the other users were seeing, but it’s relevant.
First, calling variation
doesn’t do any I/O at all; the method is synchronous in that it returns a value right away without deferring any actions, not because it performs a synchronous HTTP request (or any request).
Requests to events.launchdarkly.com
are for posting analytics events (such as the ones generated by variation
). That normally happens in an asynchronous flush task that is triggered by setTimeout
, and the request itself is also async.
What you’re seeing is a special case. There is a beforeunload
handler that is called whenever the current page is about to go away. It checks if there are any events waiting to be sent (i.e. if the flush task has not yet fired), and if so, it attempts to send them using a synchronous HTTP request (if it were async, it would have no chance to complete before the page got unloaded). All versions of ldclient-js have this. The intention is to minimize any loss of analytics events, so that your dashboard is as up to date as possible, without requiring you to use a very short event flush interval.
We suspected that browsers might stop supporting this kind of thing at some point, but we hadn’t seen this specific change in Chrome, so thanks for that. We’ll have to think about the best way to adapt. As for why you were seeing it a little before, but now are seeing it a lot, I would guess that either more of your users have the latest Chromium now, or for whatever reason your application is generating events more often than it used to so it’s more likely to have some unsent ones in the queue at page unload time.
The reason I doubt that the other comments had the same cause is that they didn’t include the «Synchronous XHR in page dismissal» message; I’m assuming they didn’t just forget to copy that, since it’s pretty distinctive.
Has this ever happened to you? You’re working on the code for your Angular app. And since you’re an amazing developer, you’re also writing test specs using Jasmine. You want to run your tests so you pop down to the terminal and type ng test
to execute your tests.
You expect to have everything run and pass but instead you get a half-zillion test failures and lots of them have a weird and completely unhelpful error message:
Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest'
WHAT — IS — GOING — ON?!?!?!?!
It’s Not the Real Error
The problem here is that the real error message is hidden. I don’t remember where I learned this trick but it’s helped me out a bunch of times in my Jasmine tests for Angular.
Instead of running your tests with the ng test
command, use ng test --source-map=false
.
The Real Error Revealed
Ok. So this time, you head to the command prompt (shell, terminal, etc) and you run ng test --source-map=false
.
This time you’ll get a much better error. In this case, the error message is «NullInjectorError: R3InjectorError(DynamicTestModule)[FormBuilder -> FormBuilder]: NullInjectorError: No provider for FormBuilder!
«
It’s Almost Always a Dependency Problem
The underlying problem is almost always some kind of missing dependency that’s causing the Angular dependency injection / IoC framework to panic.
So when our typescript or javascript code gets executed, it goes through something like a compilation process that take the human-readable code and turns it into something that can be executed efficiently. In the case of typescript, there’s an extra step and the code gets ‘transpiled’ into javascript before execution. The source map is supposed to help us to debug our code by connecting the instructions that are being executed to the source code that inspired those instructions. If we didn’t have that, it would be a whole lot harder to debug our apps.
My theory on why ng test –source-map=false helps in these weirdo error cases is that because of the type of problem (dependency injection problems), the source map thinks that the problem is in the dependency injection framework rather than in your code that configures the dependencies.
So. By turning off the source map generation, you get the real error.
(Disclaimer: that theory could be wildly wrong…but it makes sense to me.)
A Little More About My Error
So this blog post is about how to get at the real error message but while I’m here, I figure I might as well tell you how I fixed the real error, too. Like I said, it’s almost always a dependency problem. Lately, I’ve been working on converting a bunch of template-driven angular forms over to reactive forms. This means that in my Jasmine specs, that I need to update the imports
directive to reference ReactiveFormsModule
instead of FormsModule
.
To fix this, I need to get to the call to TestBed.configureTestingModule
and find the FormsModule import. Change this over to be ReactiveFormsModule
and voila! — the problem is fixed.
Summary
In short, there’s something about dependency import problems in Jasmine tests for Angular that sometimes causes the real errors to be eaten. So if you find yourself wondering about why you’re getting that strange XMLHttpRequest error, try running your test suite without source maps. The command to do that is ng test --source-map=false
.
I hope this helps.
-Ben
— Looking for help with Angular and/or Angular testing? We can help. Drop us a line at info@benday.com.
- Remove From My Forums
-
Question
-
Hi everyone,
This is the error, comes from apache cordova ajax wcf rest post json to iis server
NetWork Error: Error: Failed to execute ‘send’ on ‘XMLHttpRequest’: Failed to load ‘http://…
With emulator it works.
Thanks a lot
All replies
-
-
Edited by
Tuesday, June 21, 2016 6:06 AM
-
Edited by
-
Thank you,
I tried this. but it still does not work.
the error is the same.
My case is ajax from android device to iis server, maybe it requires something special?
Thank you.
-
Hi,
Could you give a complete error message? You can use fake address instead of real address.
-
Hi,
The error is :
NetworkError: Failed to execute ‘send’ on ‘XMLHttpRequest’: Failed to load ‘http://smnolines/SuperMarketWcfServices/SuperMarketWcfServices.svc/ValidateLogin’.
I have to say that with emulator it works. I am using private ip address.
smnolines is dns.
Thanks.
-
Hi,
meanwhile I changed smnolines to ip address and it still does not work but there is another error : 404 not found
-
Previous error is because of dns.
With ip address it throws error 404.
-
Hi,
Could you try ping <server ip> to see if your local machine has a good connection to the server?
-
Edited by
Elvis XiaMicrosoft employee
Wednesday, June 22, 2016 8:47 AM
-
Edited by
-
First of all ping is works.
My configuration is that develop pc and iis are on the same pc.
I do not have another iis server.
I have also the router which my android device is using.
I did necessary changes on router parameters , like ip and port.
My device works with no problems. -
@ness-ness
I know this is a really old thread.
But how were you able to resolve the issue?
I am supporting a cordova app and am having the same issue.
Thanks,
-
Thanks for sharing the solution. SMH
Everybody Wants To Go To Heaven, But No One Wants To Die!
-
dear please will you share me how you resolved this problem i am fedup . my ajax Post giving Error.. Please will you help me out .. Ajax post is working on browser but not on device .