Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GET http://localhost:4200/null 404 (Not Found) in angular2 with angular-cli

I'm working with angular2 project with angular-cli. Today I updated version of below to 2.4.1.

"@angular/common": "~2.4.1", "@angular/compiler": "~2.4.1", "@angular/compiler-cli": "^2.4.1", "@angular/core": "~2.4.1", "@angular/forms": "~2.4.1", "@angular/http": "~2.4.1", "@angular/platform-browser": "~2.4.1", "@angular/platform-browser-dynamic": "~2.4.1", "@angular/router": "~3.4.1", "angular-cli": "^1.0.0-beta.24" 

When I used 2.0.0, it doesn't make an error, but now, it makes an error like GET http://localhost:4200/null 404 (Not Found).

Even though it makes an error, it's working well. However, I want to know why it happens, and fix this error. If anyone knows about this, please let me know. Thank you :)

Packages.json

{    ...        "private": true,    "dependencies": {      "@angular/common": "~2.4.1",      "@angular/compiler": "~2.4.1",      "@angular/compiler-cli": "^2.4.1",      "@angular/core": "~2.4.1",      "@angular/forms": "~2.4.1",      "@angular/http": "~2.4.1",      "@angular/material": "^2.0.0-beta.0",      "@angular/platform-browser": "~2.4.1",      "@angular/platform-browser-dynamic": "~2.4.1",      "@angular/router": "~3.4.1",      "@types/moment-timezone": "^0.2.33",      "angular-cli": "^1.0.0-beta.24",      "angular2-google-maps": "^0.17.0",      "bootstrap": "^3.3.7",      "bourbon": "^4.2.7",      "core-js": "^2.4.1",      "es6-promise": "^4.0.5",      "font-awesome": "^4.7.0",      "hammerjs": "^2.0.8",      "moment": "^2.17.1",      "moment-timezone": "^0.5.10",      "node-sass": "^3.13.0",      "primeng": "^1.1.0",      "pubnub-angular2": "^1.0.0-beta.6",      "quill": "^1.1.8",      "rxjs": "5.0.1",      "ts-helpers": "^1.1.1",      "typescript": "^2.0.10",      "typings": "^2.1.0",      "zone.js": "^0.7.4"    },    "devDependencies": {      "@types/hammerjs": "^2.0.33",      "@types/jasmine": "^2.2.30",      "@types/moment": "^2.13.0",      "@types/moment-timezone": "^0.2.33",      "@types/node": "^6.0.42",      "angular-cli": "^1.0.0-beta.24",      "bootstrap-sass": "^3.3.7",      "codelyzer": "~0.0.26",      "jasmine-core": "2.4.1",      "jasmine-spec-reporter": "2.5.0",      "karma": "1.2.0",      "karma-chrome-launcher": "^2.0.0",      "karma-cli": "^1.0.1",      "karma-jasmine": "^1.0.2",      "karma-remap-istanbul": "^0.2.1",      "protractor": "4.0.9",      "ts-loader": "^1.3.3",      "ts-node": "1.2.1",      "tslint": "4.2.0",      "typescript": "2.0.2"    }  }

angular-cli.json

{    "project": {      "version": "1.0.0-beta.24",      "name": "five-delivery-admin"    },    "apps": [      {        "root": "src",        "outDir": "dist",        "assets": ["assets"],        "index": "index.html",        "main": "main.ts",        "test": "test.ts",        "tsconfig": "tsconfig.json",        "prefix": "app",        "mobile": false,        "styles": [          "styles.scss",          "../node_modules/hammerjs/hammer.min.js",          "../node_modules/primeng/resources/themes/omega/theme.css",          "../node_modules/primeng/resources/primeng.min.css",          "../node_modules/font-awesome/css/font-awesome.min.css",          "../node_modules/bootstrap/dist/css/bootstrap.min.css",          "../node_modules/quill/dist/quill.core.css",          "../node_modules/quill/dist/quill.snow.css",          "../node_modules/quill/dist/quill.bubble.css"        ],        "scripts": [          "../node_modules/quill/dist/quill.min.js",          "../node_modules/hammerjs/hammer.min.js"        ],        "environments": {          "source": "environments/environment.ts",          "dev": "environments/environment.ts",          "prod": "environments/environment.prod.ts"        }      }    ],    "addons": [],    "packages": [],    "e2e": {      "protractor": {        "config": "./protractor.conf.js"      }    },    "test": {      "karma": {        "config": "./karma.conf.js"      }    },    "defaults": {      "styleExt": "scss",      "prefixInterfaces": false    }  }

tsconfig.json

{    "compilerOptions": {      "declaration": false,      "emitDecoratorMetadata": true,      "experimentalDecorators": true,      "allowSyntheticDefaultImports": true,      "lib": ["es6", "dom"],      "mapRoot": "./",      "module": "es6",      "moduleResolution": "node",      "outDir": "../dist/out-tsc",      "sourceMap": true,      "target": "es5",      "typeRoots": [        "../node_modules/@types"      ]    }  }
like image 907
Mingyu Jeon Avatar asked Dec 29 '16 02:12

Mingyu Jeon


2 Answers

So I just had an exhausting time figuring this out, but I did.

This happened to me right after doing an update as well but it had nothing to do with that.

It's definitely from a reference to a variable with a null value and it's most likely an image src attribute. At least it was for me and I'm using values from a server all over the place in my app and img src were the only things causing this and it makes sense.

I had something similar to this:

<img [src]="myData?.imageUrl">

I thought that the ? safe operator would make sure I didn't get null errors, which it generally does but it seems like when you bind to a src attribute, the browser throws an error, not the compiler. The compiler lets you bind null to it because of the safe operator, but because src is a reference URL, the browser is still looking for that URL and the console throws the error because it can't find the URL relative/app/path/null

The two ways I found to solve this:

  1. Use ngIf: <img *ngIf="myData" [src]="myData.imageUrl"/> (entire image and its src attribute never even get loaded if theres no data, avoiding the issue entirely)
  2. Use interpolation: <img src="{{ myData?.imageUrl }}"/> (NOTICE in this solution you still need the safe operator because the compiler will throw an error otherwise, as expected, but now if the value is null, then src="" instead of null, which is valid HTML and wont throw a reference error)

Hope this helps!

like image 178
HauntedSmores Avatar answered Oct 11 '22 12:10

HauntedSmores


What's happening is that some browsers (i.e. Chrome) perform some toString function on the src attribute, which causes null to become 'null' instead of '', thus triggering to the browser to look for //domain.com/null.

Some may remember ng-src from AngularJS, which was created to handle this.


Anyway, after trying a lot of options, I found the solutions to be:

<img [attr.src]="myImageUrl"/> 

It works for async too (which was mainly causing this problem for me):

<img [attr.src]="myImageUrl | async"/> 

This works because instead of setting src to either 'null' or '', the src attribute isn't set at all as long as the variable/path used is not set/resolved, therefor not triggering the error.

like image 40
Jeffrey Roosendaal Avatar answered Oct 11 '22 13:10

Jeffrey Roosendaal