0

I'm trying to send a PUT request from Angular2 (using typescript) to an API made with Laravel. I'm doing it with the FormData class because this is how I can attach a file to the request. The POST method is working great, but when I try to update my model with a PUT method the API receives an empty request.

I've made some debugging and the FormData contains the data as expected, so I'm almost sure that my data is getting lost at the PUT request.

Service:

import {Http, Headers, Response, RequestOptions} from "@angular/http";

@Injectable()
export class SensorService {

public data: Data[] = [];
public sensors: Sensor[] = [];

constructor(private http: Http,
          private authService: AuthService) {

}

updateSensor(id: number, nombreNevera: string, ciudad: string, empresa_id: number,
           tipoSensor: string, telefonoMarcado: number,
           telefonoMarcadoB: number = null, telefonoMarcadoC: number = null,
           telefonoMarcadoD: number = null, fechaCalibracion: number = null,
           temMax: number = null, temMin: number = null, humeMax: number = null,
           humeMin: number = null, correos: any = null, fileToUpload: any = null) {

let formData: FormData = new FormData();

formData.append('nombreNevera', nombreNevera);
formData.append('cuidad', ciudad);
formData.append('empresa_id', empresa_id);
formData.append('tipoSensor', tipoSensor);
formData.append('telefonoMarcado', telefonoMarcado);
formData.append('telefonoMarcadoB', telefonoMarcadoB);
formData.append('telefonoMarcadoC', telefonoMarcadoC);
formData.append('telefonoMarcadoD', telefonoMarcadoD);
formData.append('fechaCalibracion', fechaCalibracion);
formData.append('humeMax', humeMax);
formData.append('humeMax', humeMin);
formData.append('temMin', temMin);
formData.append('temMax', temMax);
formData.append('correos', JSON.stringify(correos));

if (fileToUpload != null) {
  formData.append('certificado', fileToUpload, fileToUpload.name);
}

const headers = new Headers({
  'X-Requested-With': 'XMLHttpRequest'
});

return this.http.put(APPCONSTANTS.API_ENDPOINT + 'user/sensor/edit/' + id + '?token=' + this.authService.getToken(),
  formData,
  {headers: headers})
  .map((response: Response) => {
    return {
      msg: response.json().msg
    };
  });

}

}

Laravel returns an "Unprocessable Entity" because of the required fields in the controller.

2
  • 1
    You'll need to use a Content-Type header, and that's only if Laravel can process that type of put. Commented Jun 22, 2017 at 2:53
  • You will likely also need an Accept header to tell the server you want a json result. We found Firefox had an issue if we didn't have that header. developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept (Though this isn't the current issue. Try what @Z.Bagley suggested for that.) Commented Jun 22, 2017 at 2:55

2 Answers 2

1

Z. Bagley made me think that this could be a Laravel related problem and in fact it is. There's this bug causing errors when using multipart/form-data and a PUT request.

I solved the problem sending a POST request and adding _method to the form, ending with a request like this:

formData.append('_method', 'PUT');

const headers = new Headers({
  'X-Requested-With': 'XMLHttpRequest'
});
return this.http.post(APPCONSTANTS.API_ENDPOINT + 'user/sensor/edit/' + id + '?token=' + this.authService.getToken(),
  formData,
  {headers: headers})
  .map((response: Response) => {
    return {
      msg: 'sensor_updated'
    };
  });

You can let the Laravel API to listen for a PUT request:

Route::put('/sensor/edit/{id}', [
    'uses' => 'NeveraController@update'
])->middleware('jwt.auth');
Sign up to request clarification or add additional context in comments.

Comments

0

you can make put request like this

let headers = new Headers({ 'Content-Type': 'application/json', 
                                         'Accept': 'application/json;' });

         let options = new RequestOptions({ headers: this.headers });

     let body = JSON.stringify(formData);

    return this.http.put(APPCONSTANTS.API_ENDPOINT + 'user/sensor/edit/' + id + '?token=' + this.authService.getToken(),
      body ,options)
      .map((response: Response) => {
        return {
          msg: response.json().msg
        };
      });

3 Comments

Doesn't work... when printing body it seems to be empty.
turns out it was a Laravel bug. I already solved the problem, thank you anyways!
@levis can you post your solved. I meet this problem too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.