Argument error in genserver start_link call

I’m using a Romeo library to connect to an XMPP client https://github.com/scrogson/romeo.

the connection is simple when I’m using the mention steps in docs


alias Romeo.Stanza

alias Romeo.Connection, as: Conn

opts = [jid: "romeo@montague.lit", password: "iL0v3JuL137"]

# Start the client
{:ok, pid} = Conn.start_link(opts)

Till this, it’s working fine.

So now the same thing I’m doing using genserver

    def start_link(config) do
      GenServer.start_link(__MODULE__, xmpp_config, name: @name)
    end

   def init(config) do
    opts = [jid: xmpp_config.jid, password: xmpp_config.password]
    {:ok, conn} = Conn.start_link(opts)

    {:ok, %{conn: conn, user_name: xmpp_config.user_name, rooms: [], queue: []}}
  end

config = [jid: “romeo@montague.lit”, password: “iL0v3JuL137”]

trying to pass this config calling start_link function and passing config as the argument. But I’m getting argument error

{:error,
 {:badarg,
  [
    {:erlang, :apply,
     [[jid: "romeo@montague.lit", password: "iL0v3JuL137"], :jid, []], []},
    {Testapp.XMPPClient, :init, 1,
     [file: 'lib/testapp_web/channels/xmpp_client.ex', line: 12]},
    {:gen_server, :init_it, 2, [file: 'gen_server.erl', line: 374]},
    {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 342]},
    {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}
  ]}}
** (EXIT from #PID<0.1152.0>) shell process exited with reason: an exception was raised:
    ** (ArgumentError) argument error
        :erlang.apply([jid: "romeo@montague.lit", password: "iL0v3JuL137"], :jid, [])
        (testapp 0.1.0) lib/testapp_web/channels/xmpp_client.ex:12: Testapp.XMPPClient.init/1
        (stdlib 3.12.1) gen_server.erl:374: :gen_server.init_it/2
        (stdlib 3.12.1) gen_server.erl:342: :gen_server.init_it/6 
        (stdlib 3.12.1) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

What am I missing here?

How does it even compile ? xmpp_config is not defined in your function.

    def start_link(config) do
      GenServer.start_link(__MODULE__, config, name: @name)
    end
   def init(config) do
    opts = [jid: config.jid, password: config.password]
    {:ok, conn} = Conn.start_link(opts)

    {:ok, %{conn: conn, user_name: config.user_name, rooms: [], queue: []}}
  end

Sorry, I forgot to change here. It was like that only. I tried to change a variable name here

Your config seems to be a Keyword and not a Map, so I guess you have to call config[:jid] and not config.jid.

Can I pass a map in start_link like this %{config: config}?

Well if you do that you are just wrapping your problem in a map. You may want to convert config to a map (Map.new(config)) instead of wrapping it. But a keyword is fine.

Thanks.