Kurisu
How can I access variable defined in "With" statement from its "else" block?
Hello forum!
I’m trying to retrieve an updated conn, returned in the first line of a “with” statement, when second line failed. But I’m getting some error that says new_conn variable doesn’t exist. In the “do” block it is fine though.
Let me show you what my code looks like:
def some_action(conn, params) do
with {:ok1, some_result, new_conn} <- some_func(conn, params),
{:ok2, another_result} <- another_func(some_result)
do
new_conn |> redirect(to: some_path(conn, :index)) # new_conn is accessible here
else
{:error1, message} -> render(conn, "some_error_template.html")
# new_conn is not accessible here
{:error2, message} -> render(new_conn, "other_error_template.html")
end
end
Please how do you think I could get new_conn in the “else” block?
I have an idea but I’m wondering if it is not bad to use a function such as Tuple.append/2 to ensure the new_conn is present in the matching tuple…
Marked As Solved
peerreynders
You don’t.
You probably ran into this:
You’re building values.
So
iex(1)> fun = fn () ->
...(1)> with a <- 1,
...(1)> {2,_} <- {3,a} do
...(1)> :ok
...(1)> else
...(1)> {_,a} = error ->
...(1)> {:error, error, a}
...(1)> error ->
...(1)> {:error, error}
...(1)> end
...(1)> end
#Function<20.127694169/0 in :erl_eval.expr/5>
iex(2)> fun.()
{:error, {3, 1}, 1}
iex(3)>
So you just have to build the value that contains all the information that you need for the error.
The code in the OP would then look something like this:
def some_action(conn, params) do
with {:ok1, some_result, new_conn} <- some_func(conn, params),
{{:ok2, another_result},_} <- {another_func(some_result), new_conn}
do
new_conn |> redirect(to: some_path(conn, :index)) # new_conn is accessible here
else
{:error1, message} -> render(conn, "some_error_template.html")
{{:error2, message}, new_conn} -> render(new_conn, "other_error_template.html")
end
end
Also Liked
ntalfer
thanks @peerreynders
based on this thread, I ended by creating a kind of accumulator that gathers all results got during the multiple clauses
this more generic solution looks like:
with {{:ok, res1}, acc} <- {fun1(), []},
{{:ok, res2}, acc} <- {fun2(), acc ++ [res1]},
...
{{:ok, resN}, acc} <- {funN(), acc ++ [resN-1]} do
# do some stuff...
else
{error, acc} ->
# error contains the result of funP
# acc contains the results of fun1 to funP-1
# do some other stuff...
end
thanks!
idi527
idi527
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










