2017-10-11 4 views
2

J'utilise HTTPoison et Poison pour décoder une réponse de JSON à la vue. J'ai réussi à décoder le corps de la réponse, mais j'ai du mal à l'obtenir. Je reçois cette erreur: cannot encode maps inside lists when the map has 0 or more than 1 elementsPassage décodé JSON à la vue avec Phoenix

Voici ce que je fais dans le contrôleur:

url = "https://api.sportradar.us/nba/trial/v4/en/games/2016/11/06/schedule.json?api_key={api_key}" 

case HTTPoison.get(url) do 
    {:ok, %{status_code: 200, body: body}} -> 
    decoded_json = Poison.decode!(body) 
    redirect(conn, to: schedule_path(conn, :index, decoded_json)) 
    {:ok, %{status_code: 404}} -> 
end 

Puis-je transmettre la réponse à la redirection comme ça? Je pense que c'est la mauvaise façon de s'y prendre?

+1

Vous pouvez passer le JSON comme argument GET, mais ce n'est probablement pas une bonne idée. Pourquoi n'appelez-vous pas directement votre fonction de vue au lieu de la rediriger vers une autre page? – Dogbert

+0

oui, cela semble être une étrange façon de faire les choses ... – ryanwinchester

+0

@Dogbert Toute chance que vous pouvez me diriger vers par exemple de cela? – Bitwise

Répondre

2

Votre contrôleur devrait probablement rendre les données/vue que vous voulez au lieu de rediriger vers un autre contrôleur avec vos données. Les redirections sont généralement pour quelque chose comme, après avoir effectué une action, comme peut-être une demande POST réussie et faire quelque chose avec les données dans la demande, vous êtes redirigé vers une autre page. Ils ne sont généralement pas utilisés pour envoyer des données d'une méthode de contrôleur à une autre. Je ne sais pas ce que vous essayez d'accomplir afin que mon exemple ne puisse être aussi bon que mes suppositions. Cependant, voici une façon de le faire qui a probablement plus de sens que ce que vous essayez de faire. J'espère que cela devrait au moins vous aider à aller dans une meilleure direction:

defmodule MyAppWeb.MyController do 
    use MyAppWeb, :controller 

    alias MyApp.MyScheduleThing 

    action_fallback MyAppWeb.FallbackController 

    def index(conn, %{"date" => date} = params) do 
    with {:ok, schedule} <- MyScheduleThing.get_schedule(date) do 
     render(conn, "schedule.html", schedule: schedule) 
    end 
    end 
end 

Et votre module pour faire tout ce qui

defmodule MyApp.MyScheduleThing do 
    @moduledoc """ 
    A module in another file to do your HTTP fetching. 
    """ 

    @doc "Do your thing" 
    def get_schedule(date) do 
    url = url_from_date(date) 

    case HTTPoison.get(url) do 
    {:ok, %{status_code: 200, body: body}} -> 
     {:ok, Poison.decode!(body)} 
    {:ok, %{status_code: 404}} -> 
     {:error, :not_found} 
    {:error, _err} -> 
     {:error, :internal_server_error} 
    end 
    end 

    defp url_from_date(date) do 
    "https://api.sportradar.us/nba/trial/v4/en/games/#{date}/schedule" 
    end 
end 

Le :internal_server_error retour pourrait ne pas être ce que vous voulez là-bas, alors pensez de celui-ci comme un espace réservé que je mets sans connaissance de votre application ou de vos intentions.

Le {:error, :not_found} devrait effectivement le faire frapper le contrôleur de secours, lorsque l'instruction with ne correspond pas. The default one matches on that. Vous pouvez ajouter plus de méthodes pour correspondre dans votre propre contrôleur de repli pour répondre à vos besoins. Rien de tout cela n'est probablement ce que vous voulez vraiment (comme je l'ai dit, je ne sais pas ce que vous faites), mais devrait au moins vous aider à vous placer dans une meilleure direction avec les contrôleurs.

+0

Merci Ryan. C'était super instructif! – Bitwise