2017-05-22 2 views
0

J'ai cette épopée redux-observable qui fait une demande POST ajax en utilisant RxJS.ajax.post et je ne pense pas qu'il frappe mon routeur Elixir correctement car rien ne se passe sur mon backend elixir. Je reçois des demandes pour obtenir des catégories correctement et de la même manière, donc je suis correctement sur d'autres chemins dans mon routeur Elixir. Je m'attends à la question d'être avec mon code Elixir backend pas mon frontend. Je pourrais avoir besoin de changer mon chemin en router.ex.Ajax demande POST ne pas atteindre le chemin du routeur Elixir

Lorsque j'appuie sur un bouton sur le frontend, cet objet est ce qui est envoyé au backend élixir (l'envoie cette action avec un produit comme la charge utile et frappe l'épopée redux observable ci-dessous):

onPress = {() => { 
    props.uploadProduct({ 
    name: props.name, 
    brand: props.brand, 
    description: props.description, 
    image: props.image 
    }) 

l'épopée:

import { ajax } from 'rxjs/observable/dom/ajax' 
import { Observable } from 'rxjs' 

export const uploadProductEpic = action$ => 
    action$.ofType(UPLOAD_PRODUCT) 
    .mergeMap(action => { 
     ajax.post('http://localhost:4000/products/', action.payload) 
    }) 
    .map(response => uploadProductFulfilled(response)) 
    .catch(error => Observable.of(
     uploadProductRejected(error)) 
    ) 

le routeur élixir:

defmodule Api.Router do 
    use Plug.Router 

    if Mix.env == :dev do 
    use Plug.Debugger 
    end 
    plug :match 
    plug :dispatch 

    get "/categories/" do 
    Api.Repo.getCategories(conn) 
    end 

    post "/products/:product" do 
    IO.puts inspect conn 
    Api.Repo.insertProduct(conn, product) 
    end 
end 

IO.puts inspect conn n'enregistre rien. Donc, mon chemin de routeur Elixir post "/products/:product" do n'est pas touché par ma demande POST. Qu'est-ce que je fais mal?

Ceci est la fonction d'élixir dans repo.ex que je l'espère insérer le produit dans ma base de données:

def insertProduct(conn, product) do 
    product = %Api.Product{name: product.name, brand: product.brand, description: product.description, image: product.image, rating: 0, numberOfVotes: 0} 
    changeset = Api.Product.changeset(product) 
    errors = changeset.errors 
    valid = changeset.valid? 
    case insert(changeset) do 
     {:ok, product} -> 
     conn 
      |> put_resp_content_type("application/json") 
      |> send_resp(200, Poison.encode!(%{ 
       successs: "success" 
      })) 
     {:error, changeset} -> 
     conn 
      |> put_resp_content_type("application/json") 
      |> send_resp(500, Poison.encode!(%{ 
       failure: "Errors" 
      })) 
    end 
    end 

Je suis un développeur frontend juste essayer d'entrer dans Elixir Il en est ainsi apprécié toute orientation et de patience. Merci.

+0

Votre code JS est Affectations à '/ products', pas'/produits /: Product'. – Dogbert

+0

Merci. Donc, si je supprime le ': product', à partir du fichier' router.ex', est-ce que j'ai un moyen d'obtenir l'objet produit sur le backend? – BeniaminoBaggins

Répondre

1

Vos données sont envoyées dans le corps de la demande, et non pas dans l'URL, de sorte que la route doit être:

post "/products" 

Vous aurez également besoin de brancher un analyseur de JSON après plug :match et avant plug :dispatch, comme décrit dans la section Paramètres Parsing dans la documentation de Plug.Router:

plug :match 
plug Plug.Parsers, parsers: [:json], 
        pass: ["application/json"], 
        json_decoder: Poison 
plug :dispatch 

les données JSON seront désormais présents dans conn.body_params, que vous pouvez envoyer à votre fonction:

post "/products" do 
    Api.Repo.insertProduct(conn, conn.body_params) 
end 

Et enfin, les clés du JSON seraient des chaînes, vous devez donc utiliser la syntaxe de support pour les accès à la place de points:

product = %Api.Product{name: product["name"], brand: product["brand"], description: product["description"], image: product["image"], rating: 0, numberOfVotes: 0} 

Je ne sais pas comment vous 'ai défini Api.Product.changeset, mais la convention Phoenix par défaut définit une fonction 2 arité qui appelle cast et extrait les données d'une carte elle-même. Si vous faites la même chose, vous pouvez le faire à la place:

changeset = Api.Product.changeset(%Api.Product{}, product) 
+0

Merci !! Il ne semble toujours pas frapper mon routeur. J'ai essayé d'ajouter un IO.puts dans le routeur et je n'ai rien enregistré. par exemple: 'poster"/produits "do IO.puts inspecter conn Api.Repo.insertProduct (conn, conn.body_params) end' – BeniaminoBaggins

+0

Pouvez-vous voir dans la console JS si votre code 'ajax.post ('http: // localhost: 4000/products /'' est même en cours d'exécution ou pas? Vous pouvez voir les demandes faites dans le Onglet Réseau dans les DevTools de Chrome – Dogbert

+0

Mais je sais qu'il exécutait la ligne de code qui fait le POST ajax parce que cette ligne de code distribue une action qui a été envoyée '.catch (error => Observable.of ( uploadProductRejected (erreur ) ' – BeniaminoBaggins