44

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"
    ]
  }
}
Mingyu Jeon
  • 1,755
  • 5
  • 23
  • 40

7 Answers7

122

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)
starball
  • 20,030
  • 7
  • 43
  • 238
HauntedSmores
  • 1,406
  • 1
  • 11
  • 9
14

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.

Jeffrey Roosendaal
  • 6,872
  • 8
  • 37
  • 55
8

An addition to HauntedSmores answer: you can also use a ''-fallback:

[src]="myObj.img || ''"

since the elvis-operator ? is not available in .ts-files, but only in templates, you can also put this into typescript-getters.

Phil
  • 7,065
  • 8
  • 49
  • 91
1

OR When their is null/no image in our object then we can give the static image instead

HTML

<img src={{row.webimage?row.webimage:localpath}} />

Typescrpit

localpath = '../assets/img/default-user.png'

Similarly we can use binding for src attribute.

Omkar Jadhav
  • 656
  • 1
  • 5
  • 18
1

With a ternary operator:

[ngStyle]="{'background-image': myVariable ? 'url(' + myVariable.image + ')' : 'none'}"
Hypenate
  • 1,907
  • 3
  • 22
  • 38
0

In my case, the error was occurring because of using an inexistent property from my template (dumb me). My code was like this:

<img [src]='imageUrl'/>

But the underlying class for the template was having a property named:

imageURL: string;

So I changed imageUrl for imageURL and worked like a charm!

0

In my case I had the image source path dependent on several async conditions. Until these conditions were resolved the image would not load. So the browser handled it as null and presented this error. The treatment was a simple condition in the template such as:

        <span *ngIf="imagePath">
            <img [src]="imagePath" />
        </span>
        <span *ngIf=" ! imagePath">
            Loading image ...
        </span>
Felix
  • 1,662
  • 2
  • 18
  • 37