1

I have a simple method to check if a *.mp3 file in my local machine exists or not. It is supposed to return the status of the response (200, 404,403,etc), but it doesn't work.

fileExists(url){
        return this.http.get(url).timeout(2000)
                                 .map(res=>res.json())
                                 .subscribe(
                                           res=>{
                                                 console.log("res is");
                                                 console.log(res.status)
                                                 return res.status;},
                                           err =>{ 
                                                  console.log("Error is");
                                                   console.log(err.status); 
                                                   return err.status});

  }

I set a timeout for 2 seconds for it, however it only needs to check a file in my localhost. Therefore, i think, it has enough time to find the file.

it returns always:

Subscriber {closed: false, syncErrorValue: null, syncErrorThrown: false, syncErrorThrowable: false, isStopped: false…}
Sal-laS
  • 11,016
  • 25
  • 99
  • 169
  • the status returned is defined by you in the backend. no? – Mox Jan 09 '17 at 08:30
  • No, it is the status of http request. – Sal-laS Jan 09 '17 at 08:31
  • http://stackoverflow.com/questions/36628498/angular2-http-error-handling – Habeeb Jan 09 '17 at 08:34
  • @Salman, and what backend framework are u using? if you are using a backend like apache, then you are leaving it to apache to give you the status, if you are using a backend like nodejs/django, you probably need to define how the file is fetched? – Mox Jan 09 '17 at 08:34

1 Answers1

4

If you want to compose an observable that emits the status code of a GET request, you can do this:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';

this.http.get("/some-file.txt")
    .map((response) => response.status)
    .catch((error) => Observable.of(error.status || 404))
    .subscribe((status) => console.log(`status = ${status}`));

And if you want to more efficiently determine the existence of a file based on a HTTP status code, you could use the HEAD method, which won't retrieve the file's content:

this.http.head("/some-file.txt")
    .map((response) => response.status)
    .catch((error) => Observable.of(error.status || 404))
    .subscribe((status) => console.log(`status = ${status}`));

The problem with the code in your question is that you are looking for JSON content in the response and are looking for the status within that content. The status is in the response itself.

However, to implement a function that determines file existence, you don't even need to examine the status:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/mapTo';
import 'rxjs/add/operator/toPromise';

getFileStatus(path: string): Promise<boolean> {
    return this.http.head(path)
        .mapTo(true)
        .catch((error) => Observable.of(false))
        .toPromise();
}
cartant
  • 57,105
  • 17
  • 163
  • 197
  • but it does not return anything. I need it to return a boolean if it finds the file with status 200 – Sal-laS Jan 09 '17 at 18:43
  • You cannot return anything from within the `subscribe` callbacks; it just doesn't work like that. You can use the `toPromise` operator to convert the composed observable into a promise. I've updated the answer. – cartant Jan 09 '17 at 21:25
  • Can this be used for checking file exist and if not exist to load other file, thank you. – vladanPro Jan 25 '18 at 14:05