eddyraz
good Morning, I have a function that place a request to an elasticsearch REST API of a library management software, and I am trying to manipulate the response so I get the results(so far all OK), and the total results quantity(using a KErnel.tap/2 function for this). the response manipulation is as follows:
raw_response.body
|> Jason.decode!()
|> Map.fetch("hits")
|> elem(1)
|> tap(&get_total_results(&1, socket ))
|> Map.fetch("hits")
|> elem(1)
I use Kernel.tap/2 since the results is “hidden” in an upper structure of the response.
the get_total_results function is as follows:
@impl true
def get_total_results(tr,socket) do
total_res =
tr["total"]
|> tap(&IO.inspect(&1))
socket =
socket
|> assign(results_qty: total_res)
end
as soon as I use this function I get this error:
** (ArgumentError) assign/3 expects a socket from Phoenix.LiveView/Phoenix.LiveComponent or an assigns map from Phoenix.Component as first argument, got: nil.
I have read the docs but have not got anyhing clear about this, I am using assigns update in otehr parts of this module and all is OK, I thought the problem was the socket id, but is the same that I use in mount/3 in the beggining of the code, the mount/3 function is this one.
use DedalosPhoenixWeb, :live_view
use Phoenix.HTML
alias DedalosPhoenixWeb.{OpacLive, NavBarLive}
def mount(params, _session, socket) do
{:ok,
assign(socket,
page_number: 1,
page_size: 10,
results_qty: 20,
query_params: params,
filtered_results: []
)}
end
Please anyone could clear this for me, I am still readeing the official docs to see If I get something clear, thanks in advance.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex











Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
tomkonidas
Can you show us the function where you get the
raw_response? I see you pass insocketbut do not know where it comes from.eddyraz
Here is the complete function
also the build_elastic_function/2 function is here:
tomkonidas
If you
IO.inspectthe socket right before you use theassign/3? Does it returnnil?As a side note, whatever you assign to the
socketinget_total_results/2won’t be persisted as you do not return the updatedsocket.trisolaran
This code will likely not do what you think it’s doing. The result from
get_total_resultwill be discarded bytap.tapis used to perform side effects and returns its input unchanged (in this case, the result ofelem(1)).You can add a
dbg()statement at the end of the pipeline and you’ll see what I mean/al2o3cr
A general style note -
Map.fetch+elemis going to crash if the specified key is missing (sincefetchreturns a bare:error), but not with a particularly clear error message:Prefer using
Map.fetch!which will also crash, but with a message that clearly states what wasn’t found:As others have already pointed out in this thread, you’ll want to return that modified socket from
process_requestif you expect the modifiedassignsto stick around.But there’s a bigger design idea at the heart: keeping “socket manipulation” code separate from “data manipulation” code. A function like
get_total_resultsis trying to do two unrelated things and making both of them harder:totalfrom the resultsSeparating those, even if just into separate functions in the same module, can make it easier to see what’s going on (and avoid tricky “how do I return
socketfrom here?” conundrums):I’m guessing on that last one, but it seemed logical that you’d want the results to go with the count in the assigns…
BradS2S
I could be wrong but I think it is better to use MyAppWeb, :html for functional components ( or :component for 1.6) and :live_component.
One hint is that they have the Phoenix.HTML module in a separate section for modules that are “under the hood”.
Also if you look at the documentation Phoenix.HTML is imported in a private function.
Maybe consider separating your LiveView and component(s) into different modules.
eddyraz
that was my intent to create a side effect using the calling to the function
get_total_resultsand in the body of that function is where i’ d like to update the assigns. I am seeing now as tomkonidas stated that when I putIO.inspect(socket)right before theassign/3returns nil.eddyraz
when I do that it returns this,
BradS2S
I think you could do something like this.
raw_response.body
|> Jason.decode!()
|> Map.fetch(“hits”)
|> elem(1)
|> then( fn elem →
elem |> tap(&get_total_results(&1, socket ))
next = elem |> Map.fetch(“hits”)
next
end )
|> elem(1)