« Back to channel list

#elixir-lang - 21 May 2019

« Back 1 day Forward 1 day »
[00:01:11] thurloat: has joined #elixir-lang
[00:04:06] thurloat: has joined #elixir-lang
[00:05:08] sillyotter: has joined #elixir-lang
[00:08:08] thurloat: has joined #elixir-lang
[00:08:59] thurloat: has joined #elixir-lang
[00:17:36] lexmag: has joined #elixir-lang
[00:51:18] orbyt_: has joined #elixir-lang
[00:57:19] oneark: has joined #elixir-lang
[01:12:17] asabil: has joined #elixir-lang
[01:33:09] Adkron: has joined #elixir-lang
[01:40:27] tomterl: has joined #elixir-lang
[01:57:08] pera: has joined #elixir-lang
[02:05:15] Adkron: has joined #elixir-lang
[02:14:22] gvaughn: has joined #elixir-lang
[02:43:08] __charly__: has joined #elixir-lang
[02:44:43] mdbm: has joined #elixir-lang
[03:19:47] gvaughn: has joined #elixir-lang
[04:04:16] fyber: has joined #elixir-lang
[04:11:22] Adkron: has joined #elixir-lang
[04:15:30] mdbm: has joined #elixir-lang
[04:28:27] pera: has joined #elixir-lang
[04:39:03] sevenseacat: has joined #elixir-lang
[04:49:25] Adkron: has joined #elixir-lang
[04:49:51] mdbm_: has joined #elixir-lang
[05:01:58] gvaughn: has joined #elixir-lang
[05:03:46] kyrylo: has joined #elixir-lang
[05:12:28] nikhilmore54: has joined #elixir-lang
[05:14:38] Phylock: has joined #elixir-lang
[05:19:44] voltone: has joined #elixir-lang
[05:25:47] mbuf: has joined #elixir-lang
[05:35:29] syndikate: has joined #elixir-lang
[05:47:30] kapilp: has joined #elixir-lang
[05:47:39] guilleiguaran: has joined #elixir-lang
[05:51:10] mdbm_: has joined #elixir-lang
[05:57:13] syndikate_: has joined #elixir-lang
[05:58:13] gvaughn: has joined #elixir-lang
[06:00:57] kdisneur: has joined #elixir-lang
[06:07:39] DTZUZO: has joined #elixir-lang
[06:20:39] voltone: has joined #elixir-lang
[06:31:12] proteusguy: has joined #elixir-lang
[06:33:44] Phylock: has joined #elixir-lang
[06:34:54] idempotentimpala: has joined #elixir-lang
[06:40:45] gvaughn: has joined #elixir-lang
[06:43:49] voltone: has joined #elixir-lang
[06:52:53] jesopo: has joined #elixir-lang
[06:57:48] Adkron: has joined #elixir-lang
[07:18:41] PragTob: has joined #elixir-lang
[07:20:01] fastfresh: has joined #elixir-lang
[07:35:14] jkva: has joined #elixir-lang
[07:36:14] nikhilmore54: has joined #elixir-lang
[08:01:12] lexmag: has joined #elixir-lang
[08:22:00] gvaughn: has joined #elixir-lang
[08:31:12] lexmag: has joined #elixir-lang
[08:33:12] wonko7: has joined #elixir-lang
[08:39:20] Gika: has joined #elixir-lang
[08:41:01] voltone: has joined #elixir-lang
[08:47:01] ur5us: has joined #elixir-lang
[09:04:37] Adkron: has joined #elixir-lang
[09:12:27] asabil: has joined #elixir-lang
[09:22:42] BitBot: has joined #elixir-lang
[09:23:33] palidin: has joined #elixir-lang
[09:25:50] josevalim: jkva: morning!
[09:30:50] dysfun: uhoh, he's asking for you by name now jkva ;)
[09:31:12] Gika: has joined #elixir-lang
[09:43:56] ur5us: has joined #elixir-lang
[09:44:02] Adkron: has joined #elixir-lang
[09:45:20] Gazler: has joined #elixir-lang
[09:53:32] lexmag: has joined #elixir-lang
[09:55:09] snapet: has joined #elixir-lang
[09:57:39] jkva: When I first joined this channel, I wondered who this josevalim person was who frequented this channel a lot, the name sounded familiar :P
[09:58:33] jkva: dysfun: I wondered this morning how to get a hash slice, turned out it's as easy as `Map.take` :)
[10:03:20] Nicd-: jkva: wait till you find out who rvirding is...
[10:04:10] dysfun: i didn't even notice rvirding was in here
[10:04:20] dysfun: (hello robert!)
[10:07:23] Nicd-: not really active, looking at channel stats
[10:07:40] Nicd-: I have still twice as many lines as dysfun yay
[10:07:57] dysfun: he wasn't that active in #erlang-lisp either :)
[10:08:16] gvaughn: has joined #elixir-lang
[10:14:29] asabil: has joined #elixir-lang
[10:29:08] voltone: has joined #elixir-lang
[10:33:23] max_1bd: has joined #elixir-lang
[10:35:09] griffinbyatt: has joined #elixir-lang
[10:37:43] griffinbyatt: has joined #elixir-lang
[10:45:39] lexmag: has joined #elixir-lang
[10:45:44] nox: There are 3 Erlang User of the Year recipients here, right?
[10:51:12] voltone: has joined #elixir-lang
[10:54:24] lexmag: has joined #elixir-lang
[10:56:37] aither: has joined #elixir-lang
[11:01:34] kyrylo: has joined #elixir-lang
[11:10:12] mozzarella: has joined #elixir-lang
[11:11:27] tnez: has joined #elixir-lang
[11:14:52] lexmag: has joined #elixir-lang
[11:33:36] nikhilmore54: has joined #elixir-lang
[11:48:13] nikhilmore54: has joined #elixir-lang
[11:48:55] m1dnight_: I'm trying to make the simplest REST api, but i'm confused about the render functions.
[11:49:10] gvaughn: has joined #elixir-lang
[11:49:10] m1dnight_: defmodule RunnerWeb.ProgramView do
[11:49:12] m1dnight_: use RunnerWeb, :view
[11:49:14] m1dnight_: alias RunnerWeb.ProgramView
[11:49:16] m1dnight_: def render("index.json", %{programs: programs}) do
[11:49:18] m1dnight_: %{data: render_many(programs, ProgramView, "program.json")}
[11:49:22] m1dnight_: def render("show.json", %{program: program}) do
[11:49:24] m1dnight_: IO.inspect program
[11:49:26] m1dnight_: %{data: render_one(program, ProgramView, "program.json")}
[11:49:31] m1dnight_: def render("program.json", %{program: program}) do
[11:49:32] m1dnight_: IO.inspect program
[11:49:34] m1dnight_: inspect(program)
[11:49:40] m1dnight_: https://exbin.call-cc.be/ExpeditesBroils
[11:49:44] m1dnight_: So well, that link contains that text... :p
[11:50:15] ryotsu: has joined #elixir-lang
[11:50:29] Adkron: has joined #elixir-lang
[11:50:54] m1dnight_: When you call "render_one", I assumed it would just be a functioncall to render("program.json") but a lot of data i added around it
[11:51:15] m1dnight_: My idea would have been to change those functions from program to result, because my api expects a program, and returns a result
[11:51:29] m1dnight_: I don't need another resultcontroller and all that jazz. just a response
[11:55:29] lexmag: has joined #elixir-lang
[12:09:21] mdbm: has joined #elixir-lang
[12:31:17] Adkron: has joined #elixir-lang
[12:41:30] tallysmartins_: has joined #elixir-lang
[12:46:14] griffinbyatt: has joined #elixir-lang
[12:46:24] kdisneur: has joined #elixir-lang
[12:48:16] lexmag: has joined #elixir-lang
[12:56:23] lauromoura_: has joined #elixir-lang
[13:06:44] lexmag: has joined #elixir-lang
[13:15:27] kdisneur: has joined #elixir-lang
[13:21:44] gvaughn: has joined #elixir-lang
[13:30:36] Adkron: has joined #elixir-lang
[13:35:27] averell: has joined #elixir-lang
[13:37:44] asabil: has joined #elixir-lang
[13:41:14] knack: has joined #elixir-lang
[13:43:39] hypercore: has joined #elixir-lang
[13:44:14] hypercore: when should i put my js files into app.js, and when should i store them as another .js files? (which are accessible via static_path)
[13:44:39] jimmyrcom: has joined #elixir-lang
[13:46:45] lexmag: has joined #elixir-lang
[13:58:54] helpa: has joined #elixir-lang
[13:58:55] jsehop98: has joined #elixir-lang
[14:01:24] helpa: has joined #elixir-lang
[14:01:24] thurloat2: has joined #elixir-lang
[14:01:44] helpa: has joined #elixir-lang
[14:01:54] MonononcQc: has joined #elixir-lang
[14:01:55] Reapster_: has joined #elixir-lang
[14:01:59] pankracy_: has joined #elixir-lang
[14:02:02] Liquid_X_: has joined #elixir-lang
[14:02:08] Scramble1ams: has joined #elixir-lang
[14:02:10] gvaughn: has joined #elixir-lang
[14:02:22] MonononcQc: has joined #elixir-lang
[14:02:51] puzza007_: has joined #elixir-lang
[14:03:27] asabil: has joined #elixir-lang
[14:03:48] MonononcQc: has joined #elixir-lang
[14:04:54] Cthalupa-: has joined #elixir-lang
[14:04:58] Hwakheart: has joined #elixir-lang
[14:05:18] codewaffle_: has joined #elixir-lang
[14:05:21] hypercore: m1dnight_: i'm using webpack, but yeah same idea
[14:06:28] nikhilmore54: has joined #elixir-lang
[14:06:34] lpvb: has joined #elixir-lang
[14:07:19] DanielI: has joined #elixir-lang
[14:07:20] MononcQc: has joined #elixir-lang
[14:08:00] LnL: has joined #elixir-lang
[14:12:06] Phylock: has joined #elixir-lang
[14:12:14] evax: has joined #elixir-lang
[14:12:37] povilas: has joined #elixir-lang
[14:13:00] andersju: has joined #elixir-lang
[14:13:01] harfangk: has joined #elixir-lang
[14:13:01] mclee: has joined #elixir-lang
[14:13:23] phantummmm: has joined #elixir-lang
[14:13:39] lemald: has joined #elixir-lang
[14:14:41] __charly__: has joined #elixir-lang
[14:14:49] garazdawi: has joined #elixir-lang
[14:17:10] lexmag: has joined #elixir-lang
[14:20:04] Mieserkadser: has joined #elixir-lang
[14:20:48] Mieserkadser: Is there an API call to re-render my View from my UserSocket? Like getting an Event in handle_in and update the View immediately.
[14:23:04] Mieserkadser: * i mean Channel Implementation
[14:30:06] benwilson512: Mieserkadser: is this for live view?
[14:30:16] lexmag: has joined #elixir-lang
[14:30:37] benwilson512: Mieserkadser: this shouldn't be necessary if your render call is pure. Changing assigns should trigger re-render of the parts of the page that depend on that assign
[14:30:58] benwilson512: if you have impure calls like `DateTime.utc_now()` pull those out of the render call and pass them in as assigns
[14:31:05] Guest62963: has joined #elixir-lang
[14:31:19] benwilson512: ah, on a second reading, that isn't what you're doing
[14:31:24] benwilson512: this sounds like normal channels
[14:31:34] benwilson512: although it seems like live view would be a better fit
[14:32:17] Mieserkadser: benwilson512: no i would like to render out of my channel module. I know that live view would be better. Its about to learn the true differences.
[14:32:42] benwilson512: Mieserkadser: well, the channel doesn't do any rendering in the first place
[14:32:53] benwilson512: so it's less a question of re-rendering and more of a question of "how do I render at all"
[14:33:01] Mieserkadser: So then i need to handle the "rendering" on client-side right?
[14:33:15] benwilson512: you could send the client a message and have the JS client reloadthe page
[14:33:43] Mieserkadser: and what about to trigger a full page reload with a changed state?
[14:34:11] benwilson512: well, basically you'd need to embed state in the URL, or cookies
[14:34:27] benwilson512: so instead of a reload, you could have the JS just take you to a new page w/ the params in the URL
[14:34:56] lexmag: has joined #elixir-lang
[14:35:21] benwilson512: all of that is pretty ghetto compared to live view though
[14:35:51] benwilson512: you could basically build live view yourself by building up assigns and manually calling your view in your channel, pushing the HTML over the socket, and then using morphdom on the client to redraw stuff
[14:36:00] benwilson512: Buuuut then you're just literally rebuilding live view
[14:36:10] Mieserkadser: Ah yeah, make sense. I read that a regular view is just a full page reload over the delta update from live view. But I'm not sure where the full page reload actually happen.
[14:36:36] benwilson512: what do you mean where?
[14:37:30] Mieserkadser: so the interaction between client and server is basically within the channel implementation and the javascript right?
[14:38:06] benwilson512: the interaction between the client and server in all of these cases starts with a completely ordinary HTTP GET that returns completely ordinary HTML and JS / CSS assets
[14:38:32] benwilson512: the client browser then runs the JS. If you're doing a regular channel, that JS opens a websocket connection in which you can send / receive messages via a channel process on the srever
[14:39:04] benwilson512: if you're doing live view ,it does all of that exactly the same, but ON TOP of that it has JS to receive "diff" messages, and the channel on the server holds basically a virtual dom and view state to trigger re-renders and push diffs
[14:39:47] Mieserkadser: Ahh... But i cannot trigger a re-render. When i want to display new data on the same page i need to make a new GET Requests with updates state, right?
[14:40:20] benwilson512: if you're doing the regular channel, the only want to change the HTML is to either 1) have javascript that changes the HTML or 2) make a new request
[14:40:30] benwilson512: which would also be triggered by javascript in the client
[14:40:58] Mieserkadser: perfect! Thank you :D
[14:41:18] benwilson512: Mieserkadser: the main other note is about state: When doing a regular channel, there is no correspondance between the state used to render the page and the state of the channel
[14:41:22] benwilson512: they're totally different things
[14:41:50] Mieserkadser: Yeah, right. I just compared it with live view
[14:41:53] benwilson512: the server side live view code though transfers the state used to do the initial render into the live view channel process so that it can do new renders
[14:46:13] hypercore: has joined #elixir-lang
[14:55:59] m17: has joined #elixir-lang
[15:09:05] Saukk: has joined #elixir-lang
[15:10:56] aalmazan: has joined #elixir-lang
[15:11:09] kdisneur: has joined #elixir-lang
[15:12:38] lexmag: has joined #elixir-lang
[15:14:08] lexmag: has joined #elixir-lang
[15:25:25] orbyt_: has joined #elixir-lang
[15:31:48] lauromoura: has joined #elixir-lang
[15:32:53] icecreamcohen: has joined #elixir-lang
[15:39:13] kapilp: has joined #elixir-lang
[15:41:07] Adkron: has joined #elixir-lang
[15:42:02] jkva: I'm trying to build a phoenix system, running it using `mix phx.server`. I get the error that in my router, `pipeline` is an undefined function. Where should I be looking?
[15:45:48] jkva: Ah, I think I figured it out :)
[15:51:43] wsieroci: has joined #elixir-lang
[15:52:46] thurloat: has joined #elixir-lang
[16:10:42] nickjj: can someone explain this mystery around maps? i'm adding a value to a nested map inside of a condition, but when that condition evaluates to true, the map value is not being updated, but if i remove the condition the map gets updated -- here's a gist with more details: https://gist.github.com/nickjj/901e2b559bbc3b194bb49df034ec1207
[16:10:57] Gika: has joined #elixir-lang
[16:11:17] benwilson512: nickjj: assignments don't escape the lexical scope of `if `blocks
[16:11:48] jgpawletko: has joined #elixir-lang
[16:12:17] benwilson512: https://www.irccloud.com/pastebin/agms2YaH/
[16:13:10] nickjj: is the else clause mandatory?
[16:14:30] nickjj: also thanks, i was stuck on that for so long but your solution is working
[16:16:12] pera: has joined #elixir-lang
[16:16:58] benwilson512: if you don't supply it, `params` will be `nil` if the condition s not met
[16:21:00] icecreamcohen: has joined #elixir-lang
[16:21:48] orbyt_: has joined #elixir-lang
[16:22:32] nickjj: makes sense
[16:23:27] orbyt_: has joined #elixir-lang
[16:24:33] nikhilmore54: has joined #elixir-lang
[16:27:31] Gazler: nickjj: If you don't care about %{"email" => nil} being in the map you can do: params = put_in(%{"checkout" => %{"name" => "foo"}}, ["checkout", "email"], me && me[:email])
[16:27:54] Gazler: If me is nil, then nil["email"] will also be nil.
[16:28:03] benwilson512: gazler: clever
[16:28:07] Gazler: So if me is always a map or nil, then you don't even need the &&
[16:28:21] Gazler: You can just do: params = put_in(%{"checkout" => %{"name" => "foo"}}, ["checkout", "email"], me[:email])
[16:28:23] benwilson512: update_in could work here too with pattern matching
[16:28:42] benwilson512: on the update fun
[16:29:22] hypercore: has joined #elixir-lang
[16:30:19] nickjj: gazler, i'm passing that map into a changeset validation that expects the email to be present
[16:30:19] Gazler: benwilson512: Your solution is worth it to explain the if expression
[16:30:50] Gazler: nickjj: Which validation are you using?
[16:30:57] nickjj: the real reason i'm doing this is because on checkout, if the user is logged in, there is no email form field for them to put in their account (since they are logged in), so i situationally add it when a current user is present
[16:31:46] nickjj: required and also a super basic regexp to do a sanity check on the address
[16:31:53] benwilson512: gazler's put_in will work great there then
[16:32:00] nickjj: ~r/\A\S+@\S+\.\S+\z/
[16:32:51] Gazler: validate_required will fail on a nil, so put_in will work.
[16:33:35] Gazler: Ambiguous phrasing: will fail. What I mean is it'll mark the field as invalid.
[16:33:41] rawtaz_: has joined #elixir-lang
[16:33:52] nickjj: so i just remove the condition and it all works with or without a checkout.email being present in params?
[16:34:12] nickjj: if absent it adds it from current user , if present it uses that value as is?
[16:34:50] Gazler: No, if it is present then it'll nullify the email address.
[16:35:00] nickjj: also if it matters, there are other fields in checkout that i don't want to modify
[16:35:40] nickjj: would your method require me to hard code those params in there (like you did with "name")?
[16:35:56] nickjj: i kind of wanted to avoid having to hard code them
[16:36:24] Gazler: You'll need this instead. update_in(%{"checkout" => %{"name" => "foo", "email" => "abc"}}, ["checkout", "email"], fn val -> val || me["email"] end)
[16:36:35] Gazler: No, that was just for an example, you can use params.
[16:36:41] orbyt_: has joined #elixir-lang
[16:36:48] Gazler: update_in(params, ["checkout", "email"], fn val -> val || me["email"] end)
[16:37:14] nickjj: hmm that's actually quite readable
[16:37:45] nickjj: update the inner checkout map's email address and use the current value if available otherwise grab it from the current user
[16:37:51] nickjj: but what happens when the current user isn't there and me is nil?
[16:38:01] Gazler: It'll be nil.
[16:38:37] nickjj: me["email"] will fail with nil."email" not being valid?
[16:38:52] nickjj: and then throw a 500?
[16:38:52] Gazler: You can also do %{params | "checkout" => Map.put_new(params["checkout"], "email", me[:email])} if the map isn't too deep.
[16:39:17] nickjj: that was another problem i had too, i wasn't sure how to deconstruct it in a way that makes for me
[16:39:20] Gazler: nickjj: Try it in iex
[16:39:26] Gazler: nil["email"] is totally valid
[16:39:33] Gazler: It returns nil.
[16:39:35] nickjj: currently i only have 2 things being POST'd
[16:40:06] nickjj: the params contains: the "checkout" map and then a foo_id value outside of the "checkout" map
[16:40:17] nickjj: i care nothing about anything else in params besides those 2 things
[16:40:38] nickjj: but i battled the deconstruct syntax for like 20min and eventually gave up
[16:41:25] nickjj: in an ideal scenario foo_id would be available as a variable in the function and params would really just be params["checkout"]
[16:56:21] nickjj: thanks too, your update_in is working, really cool
[16:58:14] nickjj: but it does fail in the case i was worried about , in my case i'm using me.email since it's an ecto schema and that blows up
[16:58:42] nickjj: can't trust users, they might tamper with the html and remove the email field entirely from the form while logged out
[17:02:31] jnoon2: has joined #elixir-lang
[17:08:20] benwilson512: nickjj: what code did you end up with exactly?
[17:08:33] wonko7: has joined #elixir-lang
[17:08:44] nickjj: benwilson512, i reverted back to the params condition you had
[17:09:06] nickjj: because in his example he had me["email"] but in my case i am using me.email which fails when me is nil
[17:09:07] benwilson512: how can `me.email` blow up?
[17:09:24] benwilson512: if they aren't logged in?
[17:09:44] benwilson512: FWIW I never set `current_user` nil
[17:09:50] benwilson512: if the key exists, then there's a current user
[17:09:53] nickjj: correct, not logged in, but also 1 step further where they decided to tamper with the html form and remove the email field (so the first condition of gaz's solution doesn't fire)
[17:11:10] nickjj: in a perfect world where users don't mess with your code then his solution worked because a logged out user would see an email form field and then it would exist so it uses that without ever checking me.email
[17:11:16] benwilson512: gazler's thing is fine for that
[17:11:17] benwilson512: https://www.irccloud.com/pastebin/dCjuDGIK/
[17:11:36] nickjj: but change me[:email] to me.email
[17:11:49] benwilson512: it's intentionally `:email`
[17:11:54] benwilson512: if they eliminate the html field
[17:11:58] nickjj: because [:email] didn't work on an ecto schema , it said something about the fetch function not existing
[17:11:58] benwilson512: and they aren't logged in
[17:12:06] benwilson512: I implement that in all my ecto schemas
[17:12:11] benwilson512: super convenient
[17:12:20] nickjj: i have no idea what that is
[17:12:39] benwilson512: what do you have at the top of your ecto schema in terms of `use` ?
[17:13:07] nickjj: use Ecto.Schema
[17:13:50] benwilson512: gotcha. I usually have something like
[17:14:50] benwilson512: https://www.irccloud.com/pastebin/T5ZA9kJK/
[17:15:27] nickjj: is that mentioned somewhere in the docs to read up more about not using the official ecto echema in phoenix projects?
[17:16:40] nickjj: it's been a while since i read the getting started docs but i didn't recall reading anything about that
[17:16:47] benwilson512: to be clear, that does use the official ecto schema
[17:16:50] benwilson512: `use Ecto.Schema` is in there
[17:17:00] benwilson512: you could also do this
[17:17:07] nickjj: i don't know what's really going on there, but it looks like you're adding custom things to it?
[17:17:17] nickjj: things that would be available on all schemas that use this
[17:17:22] benwilson512: https://www.irccloud.com/pastebin/AgHTrJDx/
[17:17:27] benwilson512: that might be clearer ^
[17:17:46] benwilson512: `use MyApp.Access` injects the code from the `__using__` macro in `MyApp.Access`
[17:17:52] benwilson512: it's Elixir metaprogramming
[17:18:00] benwilson512: not really anything Ecto or Phoenix related
[17:18:16] nickjj: does that add fetch/get/pop, or is it changing existing behavior?
[17:18:30] benwilson512: it adds those functions to the `MyApp.Accounts.User` module
[17:18:37] benwilson512: as if you wrote them there yourself
[17:18:54] benwilson512: this will let you do `user[:email]`
[17:19:11] nickjj: besides being able to access user[:email] what are the benefits of doing that?
[17:19:19] nickjj: do you still access user.email in most areas of your code base?
[17:19:28] benwilson512: if I expect `user` to be non nil then yes
[17:19:30] nickjj: but only use user[:email] in cases like the use case that came out?
[17:19:37] benwilson512: that's exactly right
[17:19:44] benwilson512: it also works well with preloads if they can be `nil`
[17:19:47] benwilson512: but yo udon't really care
[17:20:14] nickjj: like user[:posts] instead of user.posts?
[17:20:31] benwilson512: well that won't be nil, that'll be an empty list f there aren't posts but
[17:20:32] benwilson512: something like
[17:20:51] nickjj: if posts weren't preloaded, the 2nd one probably fails right? i haven't worked with preloads much yet
[17:21:09] benwilson512: if posts aren't preloaded `user.posts` and `user[:posts]` will both return `%Ecto.AssociationNotLoaded{}`
[17:21:10] nickjj: but i think in that case, i'd probably want it to blow up
[17:21:28] benwilson512: yes, ecto doesn't use `nil` as the not loaded value
[17:21:29] benwilson512: which is great
[17:21:37] benwilson512: `nil` means "definitely not there"
[17:21:47] benwilson512: I use it for like
[17:21:53] benwilson512: `shipment[:destination][:name]`
[17:21:59] benwilson512: destination is optional on a shipment
[17:22:06] benwilson512: if it's there I want to show the name, if not, `nil` is fine
[17:22:07] nickjj: are there any implications of your fetch/get/pop functions? not that it matters, but will ecto/elixir have to do extra work to this type of lookup?
[17:22:28] nickjj: *to do this
[17:23:00] benwilson512: not particularly, if you're going for LOLspeed then you generally want to stick to the low level functions but really that's only worth bothering about if you care about every microsecond and you're doing it 1 million+ times a second or w/e
[17:23:18] benwilson512: even then, profile first
[17:23:44] benwilson512: I still recommend favoring assertive code, or code that avoids `nil` entirely
[17:23:47] nickjj: yeah this is just a run of the mill web app that has a tens of concurrent users and thousands of records
[17:23:59] benwilson512: there are very handy situations for `ecto_schema[key]`
[17:24:13] benwilson512: god I can't type right now.
[17:25:10] nickjj: btw in your 2nd gist, you changed MyApp.Schema to MyApp.Access as one of the changes
[17:25:27] nickjj: that could still remain as schema right?
[17:27:56] nickjj: oh wait, i just saw the usage is quite a bit different hmm
[17:29:00] nickjj: would you say it's a reasonable idea to use your 1st example? since then all of your schemas could just use that (and would likely have other shared functions)
[17:30:01] qgnox: has joined #elixir-lang
[17:31:13] fastfresh: has joined #elixir-lang
[17:32:42] fastfresh: GenServer is basically a loop which pattern matches on messages, inside this loop, right?
[17:35:30] icecreamcohen: a loop with a receive block, yes.
[17:40:08] fastfresh: Ok, so it receives a message, calls matching handler and then calls loop(state) again. But what about call stack? I imagine that loop(loop(loop... will eventually deplete max recursion depth
[17:46:11] Exuma: has joined #elixir-lang
[17:47:41] Adkron: has joined #elixir-lang
[17:48:29] wsieroci: has joined #elixir-lang
[17:52:32] Gika: has joined #elixir-lang
[17:56:37] gamache: fastfresh: the style is what's called "tail recursion". If you end a function with another function call in such a way that there's no additional work to do after that function returns, the VM can optimize things so no extra stack frame is needed. This is called tail call optimization.
[17:57:32] gamache: Not every VM optimizes tail calls, but the Erlang VM does. The JVM, notably, does not :(
[18:05:45] mrus: Is there a way to pattern match/guard a function that could either accept a struct or a bare map as an argument?
[18:06:16] gamache: mrus: you can match on %{__struct__: _}
[18:06:22] icecreamcohen: what do you want to guard against?
[18:06:35] icecreamcohen: you could do %StructModule{}
[18:06:57] icecreamcohen: or if you want _any_ struct %struct_module{}
[18:07:01] mrus: icecreamcohen: I tried that, but the other function that matches on %{} always matches
[18:07:10] icecreamcohen: put the second one after the first
[18:07:32] mrus: e.g. myfunc(%{} = mymap) and myfunc(%MuStruct{})
[18:07:49] icecreamcohen: right, the second one needs to be defined before the first
[18:07:52] icecreamcohen: it’s more specific
[18:08:02] gamache: more specific matches should come first in the source file
[18:08:04] mrus: uh, I hate code that relies on order :D
[18:08:16] gamache: Come up with a better way :D
[18:08:18] mrus: I think I like gamache's suggestion
[18:08:21] icecreamcohen: that’s kind of elixir’s deal.
[18:08:46] asabil: has joined #elixir-lang
[18:09:04] icecreamcohen: %{} is a pretty meaningless match though; any map
[18:09:46] icecreamcohen: you sure you want a single function head for processing a map, which has no key guarantees and a struct, which does?
[18:10:12] icecreamcohen: you could also do something like %{a_key_i_care_about: value, another_key: value}
[18:11:41] rroslan: has joined #elixir-lang
[18:13:03] mrus: well.. here's the thing. I'm actually working with Structs. But it looks like the Elixir Mongodb lib doesn't like structs and prefers to retrieve data as simple maps. Now, in order to make my integration easier to handle, I thoiught, let's write both functions: One that accepts the bare struct and forwards it to mongo, the other one that accepts the structs I'm usually working with and the other one
[18:13:09] mrus: accepts the struct, performs a Map.from_struct and then calls the first function.
[18:14:23] icecreamcohen: or, wrap your data accessors with a call to struct(MyModule, data)
[18:14:58] icecreamcohen: structs have a lot of advantages to bare maps, you should use them
[18:15:26] icecreamcohen: oh, I see what you’re saying
[18:15:37] icecreamcohen: the mongo driver doesn’t like the struct for writing data.
[18:15:46] asabil: has joined #elixir-lang
[18:17:11] mrus: I would like to use structs
[18:18:46] lauromoura: has joined #elixir-lang
[18:19:00] icecreamcohen: so, have your functions that write to the database unwrap them, and have your functions that access the database wrap the maps in structs
[18:19:18] icecreamcohen: though, that might cause problems in mongo since it’s schemaless?
[18:19:46] asabil: has joined #elixir-lang
[18:21:46] hypercore: guys what's the best way of stopping scripts/libraries (js) for certain pages being put into app.js?
[18:25:16] asabil: has joined #elixir-lang
[18:27:33] ephemera_: has joined #elixir-lang
[18:30:21] Rovanion: has joined #elixir-lang
[18:34:25] thurloat: has joined #elixir-lang
[18:42:29] wsieroci: has joined #elixir-lang
[18:42:59] work_: has joined #elixir-lang
[18:52:07] asabil: has joined #elixir-lang
[18:56:34] nageV: has joined #elixir-lang
[18:58:12] blahdodo: has joined #elixir-lang
[19:00:40] thurloat: has joined #elixir-lang
[19:06:34] asabil: has joined #elixir-lang
[19:07:50] benwilson512: mrus: embedded schemasin ecto are designed for this
[19:09:59] mrus: benwilson512: yeah, well, if I would be using ecto. :)
[19:12:22] mrus: I ended up using the suggestions from icecreamcohen and gamache, it works now. However, it still feels awkward that there's nothing like is_struct.
[19:12:50] icecreamcohen: there effectively is
[19:12:57] icecreamcohen: a specific struct or any struct?
[19:13:07] mrus: a specific struct
[19:13:11] icecreamcohen: a specif one is def foo(%MyStruct{})
[19:13:32] mrus: that's "pattern matching" I believe. Not a guard.
[19:13:44] blahdodo: has joined #elixir-lang
[19:13:53] icecreamcohen: correct, but they’re fairly interchangeable.
[19:14:33] benwilson512: the %_{} pattern will only match structs
[19:14:36] icecreamcohen: it’ll do the same thing
[19:14:41] mrus: well, that's what I'm doing know, just as you guys suggested. ANd I re-ordered the functions so the struct matching function comes first.
[19:14:58] mrus: s/know/now
[19:15:28] icecreamcohen: yeah, some struct magic is the %struct_module{} which will capture the struct module for you. I’ve only used that once
[19:15:50] icecreamcohen: mrus: I think what you’re doing is idiomatic
[19:17:53] mrus: Alright, then I'll just like to this IRC channel's log if anyone on GitHub complains. :)
[19:19:00] icecreamcohen: I can’t imagine anyone complaining abou this, it’s pretty standard
[19:19:04] icecreamcohen: but tell ‘em we sent you.
[19:29:47] serafeim: has joined #elixir-lang
[19:30:44] serafeim: could somebody explain to me with simple words (like explaining it to her grandmother) what is the "Algebra" (https://hexdocs.pm/elixir/Inspect.Algebra.html) and if I'll ever need to use it anywhere ?
[19:31:11] lexmag: has joined #elixir-lang
[19:32:07] squalloster: has joined #elixir-lang
[19:32:22] benwilson512: serafeim: you will not need to use it unless you are trying to build your own Inspect output for custom data structures
[19:33:24] serafeim: benwilson512, why use something as complex as that "Algebra" thing instead of just outputting a normal string ?
[19:33:39] benwilson512: serafeim: building the string is the complex part, not printing it
[19:33:55] benwilson512: specifically though
[19:34:15] serafeim: could you give me a concrete example ?
[19:34:38] benwilson512: sure, so you know how if you print a really big map, it doesn't show the whole thing?
[19:35:13] benwilson512: that logic is actually complex, because how much to show depends on how nested the structure is, and how big it is at each level
[19:35:30] benwilson512: what the idea of an "Algebra" gives Elixir's Inspect protocol is a way to reason about all that complexity in a predictable way
[19:35:48] benwilson512: instead of a bunch of individual rules that are hard to apply together
[19:35:57] serafeim: ok that makes more sense
[19:36:25] wsieroci: has joined #elixir-lang
[19:41:38] serafeim: is it a common practice to implement String.Chars for an Ecto.Schema ? if yes where should I put the implementation?
[19:50:14] benwilson512: serafeim: it is not no
[19:50:54] benwilson512: schemas aren't usually a form of textual data that has a single sensible textual representation
[19:51:19] benwilson512: what is your use case?
[19:51:52] benwilson512: are you trying to do something like this? serafeim https://hexdocs.pm/elixir/Inspect.html#module-deriving
[19:53:09] serafeim: well I have a User schema and I want to write IO.puts %User{} and not receive an error
[19:53:32] benwilson512: why do you want to do that?
[19:53:57] benwilson512: IO.inspect %User{} is more common
[19:54:01] benwilson512: and also works out of the box
[19:54:02] serafeim: because for example I am using that in some eex templates and I want to output it
[19:54:10] serafeim: benwilson512, yes I know about inspect
[19:54:40] benwilson512: I guess my point is
[19:54:41] serafeim: I said "IO.puts" because if I understand correcly it has the same behavior as <%= %User %>
[19:54:44] benwilson512: a User isn't character data
[19:55:00] serafeim: <%= %User{} %>
[19:55:11] benwilson512: you should write a function that takes a user as input
[19:55:17] benwilson512: and returns the right string for that particular use case
[19:55:28] benwilson512: not create an application wide string representation for a user
[19:56:14] benwilson512: this is about separation of presentation from data model
[19:56:49] serafeim: benwilson512, hm ok. I guess I was influenced by the django model __str__ method
[19:57:06] benwilson512: what would that output?
[19:57:06] serafeim: so I guessed that something similar would be common practice for elixir
[19:57:19] Adkron: has joined #elixir-lang
[19:57:35] serafeim: well for django when you define a model it is common to define an __str__ method that outputs a string representation of that particilar model instance
[19:57:43] benwilson512: and you expose that to end users?
[19:57:46] benwilson512: or just use it for debugging?
[19:58:09] serafeim: no it is exposed in various places
[19:58:18] benwilson512: weird. do you put like HTML in there?
[19:58:37] serafeim: for example if you have a dropdown of users the default value of the options would be the __str__ of each instance
[19:58:56] benwilson512: right, that's exactly the kind of thing that has no business sitting in the schema
[19:58:57] serafeim: no you usually just put text there
[19:59:00] benwilson512: from Elixir's point of view
[19:59:11] benwilson512: and even Rails for that matter
[19:59:22] benwilson512: data model should be split from presentation
[19:59:25] serafeim: here's a description of __str__ https://docs.djangoproject.com/en/2.2/ref/models/instances/#django.db.models.Model.__str__
[20:00:02] benwilson512: closest thing in Elixir would be something `def to_string(%User{} = user)` in your view module
[20:00:06] benwilson512: that would be fine
[20:00:20] serafeim: benwilson512, yes I can understand your point of view and since it is the common practice in elixir I'll try to follow it
[20:01:14] serafeim: however it is not a bad thing to have; you are not obliged to use it but sometimes it is helpful as a fallback quick representation of your instances
[20:02:48] serafeim: also since String.Chars *can* be implemented for your Ecto.schema why not have that and use it if you need it ?
[20:04:04] benwilson512: serafeim: because by putting that kind of logic in the data model, instead of where you are viewing the data
[20:04:14] benwilson512: if you need to present the thing in two places
[20:04:20] benwilson512: that one function starts getting complex
[20:04:27] benwilson512: it promotes a bad pattern
[20:05:34] serafeim: hm ok but then what's the point of implementing the String.Chars protocol ?
[20:05:46] serafeim: since I can use inspect for debugging?
[20:06:42] benwilson512: serafeim: it's useful for things that have straight forward singular textual representations. for example
[20:06:57] benwilson512: iex(1)> IO.puts %Geo.Point{} #=> POINT(0 0)
[20:07:23] benwilson512: the Geo.Point struct represents a standardized value that has a an actual standardized string representation
[20:07:41] benwilson512: IO.puts DateTime.utc_now #=> 2019-05-21 20:07:34.463371Z
[20:08:46] benwilson512: I'm not saying it's _never_ correct to do it with an ecto schema, but the way you handle ecto schemas is almost always more complex over time
[20:08:55] benwilson512: so it's worth setting up that separation so you don't paint yourself into a corner
[20:09:13] serafeim: let's say that I have an Ecto.Schema with a single field (name). can't I just implement String.Chars to output that field (name) ?
[20:09:16] asabil: has joined #elixir-lang
[20:09:43] serafeim: all right thanks
[20:09:49] serafeim: continuing with this discussion
[20:09:58] benwilson512: personally, I'd prefer to just <%= user.name %>
[20:10:11] benwilson512: it's more explicit, and if you make a change to the String.Chars implementation
[20:10:22] benwilson512: you'll have to audit absolutely everywhere where you print a user
[20:10:25] benwilson512: to make sure that it still makes sense
[20:10:48] serafeim: i've created a "view_helpers" module that contains a bunch of "view helper functions" i.e function that (for example) output a user representation
[20:11:45] serafeim: i then import that module to the project_web.ex file so that it will be available in all my views
[20:11:54] serafeim: is this a better approach ?
[20:11:57] icecreamcohen: has joined #elixir-lang
[20:12:08] benwilson512: I think there are certain helpers where that makes sense
[20:12:13] serafeim: for example let's say I have a function there named user_to_string()
[20:12:15] benwilson512: I think some helpers should stay in the views
[20:12:23] benwilson512: I'd consider UserView.to_string(user)
[20:12:26] benwilson512: from other views
[20:13:00] benwilson512: or better `UserView.full_name(user)`
[20:13:20] serafeim: hmmm yes that could also work it's just that I'll need to write UserView.function() many times in my templates
[20:13:37] serafeim: if i need to output a user many times
[20:14:07] benwilson512: sure, but `UserView` is not much longer than `user_`
[20:14:16] benwilson512: and it prevents your `ViewHelper` from getting very long
[20:14:23] serafeim: yes probably. and it definitely is better to organize it that way
[20:14:37] benwilson512: in my experience giant disorganized modules are more of a problem than a few extra characters for any project that's older than like 6 months
[20:15:03] serafeim: also it's probably the reason "Views" exists (because till now my view modules are nearly empty)
[20:15:14] benwilson512: views exist for two reasons
[20:15:16] benwilson512: 1) this stuff
[20:15:22] benwilson512: 2) They're actually where the templates get compiled
[20:15:31] benwilson512: the templates become functions inside that module
[20:16:27] serafeim: yes I remember that
[20:17:14] serafeim: i'll try to refactor my project following you recommendations thank you very much!
[20:19:10] serafeim: concerning the "view helpers" module I mentioned earlier
[20:20:39] serafeim: i've got a function that outputs a date in my local timezone; is this something that could go to the view helpers module ?
[20:20:47] serafeim: actually i've got it here: https://github.com/spapas/phxcrd/blob/master/lib/phxcrd_web/views/view_helpers.ex
[20:21:34] asabil: has joined #elixir-lang
[20:22:25] mahmudov: has joined #elixir-lang
[20:23:11] benwilson512: serafeim: yeah, I definitely have that sort of thing in a global helper
[20:23:36] serafeim: excellent !
[20:23:50] benwilson512: serafeim: your String.to_atom call here https://github.com/spapas/phxcrd/blob/master/lib/phxcrd_web/views/view_helpers.ex#L5 is extremely dangerous though
[20:23:55] benwilson512: although it doesn't seem like you use that function
[20:24:35] benwilson512: if you're passing in params from a controller there then you are letting end users create an infinite number of atoms, which will crash your server
[20:24:49] serafeim: yes you are right
[20:25:06] serafeim: "you should never allow users to create atoms"
[20:25:19] benwilson512: anyway, I gotta run
[20:25:31] benwilson512: seems like you're on the right track with a lot of stuff though!
[20:25:53] serafeim: actually I use that method in my templates: https://github.com/spapas/phxcrd/blob/master/lib/phxcrd_web/templates/authority/index.html.eex
[20:26:00] serafeim: benwilson512, thanks for all the help
[20:26:05] benwilson512: ah yeah, don't do that ;)
[20:26:17] serafeim: but i'll probably need to refactor it to *not* convert the user input to atoms
[20:26:23] benwilson512: the simplest option
[20:26:30] benwilson512: is to Map.take only the params you want to allow
[20:26:38] benwilson512: then you can convert those to existing atoms
[20:26:51] benwilson512: anyway, later!
[20:26:59] serafeim: benwilson512, thanks ! good bye
[20:30:26] wsieroci: has joined #elixir-lang
[20:31:00] mrus: Does anyone know how this could be achieved? https://pastebin.com/dkvs9bbL
[20:32:08] mrus: I need to return with a conn, however, I would like to remove the tmpfile after it was sent to the client - which only happens in the returned conn.
[20:32:54] ur5us: has joined #elixir-lang
[20:33:07] mrus: Now Go's `defer` would come in handy
[20:39:46] Adkron: has joined #elixir-lang
[20:40:22] netrino_: has joined #elixir-lang
[20:40:36] mrus: Apparently this was solved before: https://github.com/CargoSense/briefly
[20:41:30] icecreamcohen: mrus: doesn’t reply return when the reply is sent?
[20:42:49] starbelly: mrus: Use an async Task... also I would not have that logic in your controller.
[20:43:23] starbelly: If you want to ensure this happens without a doubt, make a genserver, call it (not cast) to remove the file
[20:44:35] icecreamcohen: I think the problem is to find out if the person is done downloading the file
[20:44:40] icecreamcohen: but I think it’s synchronous.
[20:44:44] icecreamcohen: so that’s not a problem.
[20:44:56] mrus: starbelly: yeah, I thought "let's just quickly remove it here and fine", but apparently running a GenServer is also what this breifly lib does.
[20:44:58] icecreamcohen: mrus: am I understanding your problem correctly?
[20:45:31] mrus: icecreamcohen: the issue here is that the framework I'm using (Maru) expects a controller to return a conn
[20:45:45] Zarathu_: do phoenix live views behave like genservers in that they process one message at a time?
[20:45:56] Zarathu_: or is it possible to send multiple concurrent messages?
[20:46:20] starbelly: "Files are removed after the process that requested the file dies"
[20:46:36] starbelly: So, if you don't want to use that dep... just pass the pid on fron the controller or conn
[20:46:58] starbelly: Put a monitor on the process, when you get an exit signal, remove the file
[20:47:31] benwilson512: Zarathu: each view is a genserver
[20:47:40] Zarathu: i just saw that in the src
[20:47:44] mrus: starbelly: cool, thanks
[20:47:49] Zarathu: `use GenServer`
[20:47:59] benwilson512: Zarathu: you can have multiple views within a single page however if you want concurrency there
[20:48:10] Zarathu: yea i'm gonna have to
[20:48:19] benwilson512: Zarathu: use case?
[20:49:00] Zarathu: 4 tabs on a page that show a different table of data. (columns/rows are the same). each of the 4 tables takes a long time to generate
[20:49:12] Zarathu: right now 4 async JS calls are made so they load whenever they come in
[20:49:28] benwilson512: is the slow part rendering or data loading?
[20:49:34] benwilson512: do you need to render tabs you can't see?
[20:49:40] Zarathu: data loading. i *could* use Repo.stream
[20:49:46] Zarathu: the queries are complicated
[20:50:13] Zarathu: actually Repo.stream wouldn't help. it's not a lot of data, just the computation is slow
[20:50:19] Zarathu: tasks could work!
[20:50:29] benwilson512: I'd use multiple concurrent views if that is your rendering need, otherwise use concurrency _within_ a view
[20:50:41] Zarathu: i really like the task idea, that's great
[20:51:08] benwilson512: you can even have them send their data to your view async
[20:51:15] benwilson512: and so you render each as they come
[20:51:30] benwilson512: and put a loading... thing in the actual view till the data for that part shows up
[20:51:35] Zarathu: yea just pid = self() and then send(pid, ...) in the task fn
[20:52:13] Zarathu: this is great! live view is really awesome
[20:52:17] starbelly: ACTION failed at that, but that's ok
[20:52:17] benwilson512: it really is :)
[20:52:36] Zarathu: starbelly: failed at what
[20:52:48] starbelly: At my thumbs up
[20:53:04] Zarathu: oh! the missing :. i still use irssi. haha
[20:53:48] Zarathu: holy shit, it's been 15 years already
[20:53:51] laut: has joined #elixir-lang
[20:53:56] starbelly: Then I did not fail :)
[20:54:05] starbelly: I partially failed
[20:54:39] netrino: has joined #elixir-lang
[20:54:43] Zarathu: wtf. seems like yesterday i was writing perl scripts for irssi in the early 2000s
[20:54:51] Zarathu: that was quick
[20:55:46] netrino: has joined #elixir-lang
[20:56:27] starbelly: Seems like yesterday I was going off on a tangent about security in #linpeople in BitchX
[20:57:13] Zarathu: they should really slow down the whole 'time' thing
[20:57:26] Zarathu: (side note, life breakpoints would be nice)
[21:04:53] nickjj: if i understand this correctly, once telemetry ships with phoenix, in theory you wouldn't even need to use google analytics to track and gain insights on your traffic?
[21:05:26] nickjj: if phoenix/plug emit telemetry events then you'll be able to see all of that quite easily by default, even down to specific controller actions being called?
[21:08:35] netrino_: has joined #elixir-lang
[21:08:40] hypercore: has joined #elixir-lang
[21:12:13] josevalim: google analytics measures a bunch of other diferent stuff
[21:12:18] josevalim: it is mostly focused on the client
[21:12:25] josevalim: while telemetry is all about the server
[21:12:54] nickjj: one of the main things i use GA for is just seeing things like "what were the most popular page views this month"
[21:13:40] netrino: has joined #elixir-lang
[21:19:15] netrino: has joined #elixir-lang
[21:20:51] netrino: has joined #elixir-lang
[21:23:02] helmut_1: has joined #elixir-lang
[21:23:42] helmut_1: has left #elixir-lang: ()
[21:24:25] wsieroci: has joined #elixir-lang
[21:33:23] notzmv: has joined #elixir-lang
[21:33:53] nikhilmore54: has joined #elixir-lang
[21:45:01] josevalim: yeah, telemetry is not goinig to help with that
[21:45:14] josevalim: telemetry is about sending the data to a proper metrics/monitoring system
[21:47:45] __charly__: has joined #elixir-lang
[22:11:34] icecreamcohen: has joined #elixir-lang
[22:48:16] Adkron: has joined #elixir-lang
[22:52:29] weird_error: has joined #elixir-lang
[23:01:41] __charly__: has joined #elixir-lang
[23:06:23] Adkron: has joined #elixir-lang
[23:09:25] netrino: has joined #elixir-lang
[23:12:15] wsieroci: has joined #elixir-lang
[23:13:03] MissingNoIOI: has joined #elixir-lang
[23:17:33] nickjj: josevalim, yeah, telemetry to get the data and then statsd/prom to gather it and then something else to display it
[23:18:00] nickjj: the talk i was watching eventually answered my question, it seems like a yes, but it will take time for phoenix 1.5+ to come out and then have /metrics available out of the box
[23:18:32] netrino: has joined #elixir-lang
[23:22:20] nageV: has joined #elixir-lang
[23:27:33] netrino: has joined #elixir-lang
[23:32:16] MissingNoIOI: has joined #elixir-lang
[23:35:05] nageV: has joined #elixir-lang
[23:40:21] Sgeo_: has joined #elixir-lang
[23:42:01] asabil: has joined #elixir-lang
[23:46:23] asabil: has joined #elixir-lang
[23:55:32] asabil: has joined #elixir-lang
[23:58:38] asabil: has joined #elixir-lang