Problema con Http post Angularjs2

publicado por: Anonymous

he seguido el tutorial de formularios en la documentación de Angularjs2, pero no consigo enviarlo por el método post

He creado la clase como en el ejemplo

export class Hero {
   constructor(
     public id: number,
     public name: string,
     public power: string,
     public alterEgo?: string
   ) {  }
}

Luego la llamo de esta forma

    this.hero = new Hero(42, 'SkyDog',
                   'Fetch any object at any distance',
                   'Leslie Rollover');

Y mi metodo de guardar es

    save(hero){     
  this.http.post('mi-url', hero,
    { headers: this.headers }).map(response => response.json())
    .subscribe(
        data => console.log('data', JSON.stringify(data)),
        error => console.log(JSON.stringify(error)),
        () => console.log('Completed')
    );      
}

ahora bien, mi objeto en consola se muestra creado correctamente, pero en laravel estoy recibiendo un objeto vacio, la respuesta que me da es “[]”, un objeto vacio

mientras que si cambio la linea y pongo

    this.http.post('mi-url', JSON.stringify(hero), etc etc);

obtengo esta respuesta en laravel

    {"id":42,"name":"SkyDog","power":"Fetch_any_object_at_any_distance","alterEgo":"Leslie_Rollover"}: ""

He intentado resolverlo pero creo que estoy dejando pasar algo por alto

en laravel solo estoy retornando el objeto de esta forma

    public function store(Request $request)
   { 
     if($request->ajax())
     {
      return $request->all();
     }             
   }

solución

El método de Angular, post está definido como:

this.http.post(urlHaciaDondeEnviarLosDatos, datosAEnviar, cabecerasAdicionales)

Siendo:

  • urlHaciaDondeEnviarLosDatos la ruta que escucha tu servidor para el post. Esto lo tienes ya resuelto.

  • datosAEnviar es donde se encuentran tus dudas.

¿Por qué?

Porque tu frontEnd (Angular), está escrito en lenguaje JavaScript. Mientras que tu backEnd (Laravel), está escrito en lenguaje PHP.

Si quieres enviar un objeto JavaScript a PHP, no podrás hacerlo de manera directa ya que son diferentes lenguajes de programación. Por lo tanto, hacer:

this.http.post(..., hero, ...)

No tiene demasiado sentido, ya que tu variable hero, está referenciando un objeto JavaScript. Llegando a Laravel un objeto vacío ([]) que es el escenario que describes.

Entonces, ¿Cómo enviar datos de un lenguaje a otro?

Fácilmente puedes enviar texto plano de un lenguaje a otro. Por lo tanto una solución es convertir tu objeto de JavaScript a Texto, luego enviar ese texto y recibirlo en Laravel. Por último, convertir ese Texto a un objeto de PHP.

En resumen:

  1. Convertir Objeto Javascript a Texto.
  2. Enviar desde JavaScript(Angular) ese Texto.
  3. Recibir con PHP(Laravel) ese Texto.
  4. Convertir Texto a Objeto PHP.

Pero Texto puede ser cualquier cosa. Lo bueno, es que se estandarizaron ciertos formatos de texto para el intercambio de datos. XML es uno de ellos, JSON es el más sencillo y popular (A su vez, este formato es un subconjunto de otro llamado YAML).

  1. Para convertir en JavaScript un Objeto a Texto

Usas:

JSON.stringify(objeto);

Por lo tanto, cuando estás haciendo JSON.stringify(hero), JavaScript está convirtiendo tu objeto hero a este texto:

{
  "id":42,
  "name":"SkyDog",
  "power":"Fetch_any_object_at_any_distance",
  "alterEgo":"Leslie_Rollover"
}
  1. Luego Angular envía este texto a tu servidor.
  2. Laravel recibe esto. Y cuando muestras el contenido, ves que es ese el texto que estás recibiendo. (Aunque sin los espacios, claro)

Pero, si te quedas ahí, te estaría faltando un paso:

  1. Convertir ese texto a un objeto que pueda manejar PHP.

Esto lo consigues usando una función de PHP llamada json_decode. Entonces, para convertir ese texto en un Objeto PHP, podrías hacerlo así:

$hero = json_decode($request->getContent());

Guardando en la variable $hero tus datos. De forma que si muestras con var_dump($hero); obtendrás:

object(stdClass)#1 (4) { 
  ["id"]=> int(42) 
  ["name"]=> string(6) "SkyDog" 
  ["power"]=> string(32) "Fetch_any_object_at_any_distance" 
  ["alterEgo"]=> string(15) "Leslie_Rollover" 
}

Y podrás acceder a una propiedad en particular escribiendo, por ejemplo; $hero->name que con var_dump podrás ver: string(6) "SkyDog"

Si te parece más cómodo convertir ese texto a un Array Asociativo en vez de a un Objeto, puedes usar el segundo parámetro de json_decode:

$hero = json_decode($request->getContent(), true);

Y ahora var_dump($hero); te confirmará que es un Array:

array(4) { 
  ["id"]=> int(42) 
  ["name"]=> string(6) "SkyDog" 
  ["power"]=> string(32) "Fetch_any_object_at_any_distance" 
  ["alterEgo"]=> string(15) "Leslie_Rollover" 
}

Y podrás acceder a alguna propiedad escribiendo $hero['name'];.

Otra forma, dependiendo tu versión de Laravel (Creo que 5.2+), cuentas con un método que encapsula a json_decode. El mismo es:

$request->json()->all();

Ahora, volviendo a los parámetros de this.http.post en Angular

  • cabecerasAdicionales te servirá para decirle a Laravel que el texto que estás enviando, está en formato JSON.

Esto lo consigues escribiendo:

this.http.post(
  ..., 
  ..., 
  {headers: new Headers({'Content-Type': 'application/json'})}
)

Nota: Headers se encuentra en import { Headers } from '@angular/http';

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *