Sebb

Sebb

Load json into struct in module-attribute

I want to load a json (list of objects) into list of structs in a module attribute.
Seems like I need three modules for that.

json

[
    {"foo": 1, "bar": 2},
    {"foo": 11, "bar": 22}
]

struct

defmodule Foo do
  defstruct [:foo, :bar]
end

load into struct, note that function in reality is too complex to be added to Foos/@foos - pipe

defmodule JsonLoader do
  def load_foos(foos) do
    Enum.map(foos, &struct(Foo, &1))
  end
end

module that stores the structs in a module attribute.

defmodule Foos do
  @foos File.read!("lib/foos.json") |> Jason.decode!(keys: :atoms) |> JsonLoader.load_foos()

  def get_foo(foo) do
    Enum.find(@foos, fn f -> f.foo == foo end)
  end
end

Is there way to bring all that into one module (Foo).

Marked As Solved

LostKobrakai

LostKobrakai

There is not. You can neither execute functions of a module within its own module body nor create structs of the to be compiled module at compile time. Both the struct definition as well as the function will only be available once the module is fully compiled. At the time you provide the module attribute value the module is still being compiled.

The best you can do is 2 modules. One for the struct and one with the module attribute, by inlining the code of load_foos.

Also Liked

aziz

aziz

I’d like to challenge that claim. :grinning_face_with_smiling_eyes:

defmodule Foo do
  defstruct [:foo, :bar]

  @foos File.read!("lib/foos.json")
        |> Jason.decode!(keys: :atoms)
        |> Enum.map(&Map.put(&1, :__struct__, __MODULE__))

  def list do
    @foos
  end

  def equal? do
    @foos == [%Foo{bar: 2, foo: 1}, %Foo{bar: 22, foo: 11}]
  end
end

Foo.list() |> IO.inspect(label: "list()")
Foo.equal?() |> IO.inspect(label: "equal?()")

So you can’t use the struct function but that’s a small price to pay if you really want/need to do this. :wink:

LostKobrakai

LostKobrakai

The first is just a dump alias for the current module name. The second is creating a struct, which does do things like checking keys, and such, which does fail without the struct being defined.

&Map.put(&1, :__struct__, __MODULE__) just uses knowledge about implementation details of structs to construct them without doing all the consistency checks structs have when being constructed otherwise.

Where Next?

Popular in Questions Top

yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

We're in Beta

About us Mission Statement