Uploading multiple files: How to parse params

I am receiving a list of structs inside a list from a multiple file upload that looks like this:

[
  %Plug.Upload{
    content_type: "image/png",
    filename: "android-chrome-512x512.png",
    path: "C:\\Users\\User\\AppData\\Local\\Temp/plug-1554/multipart-1554324778-248107889529445-4"
  },
  %Plug.Upload{
    content_type: "image/png",
    filename: "image.png",
    path: "C:\\Users\\User\\AppData\\Local\\Temp/plug-1554/multipart-1554324778-459840369929074-4"
  }
]

I need to:

  1. Reduce this list to just the path names ie ["c:\\filepath", "c:\\filepath"]
  2. Save both of those files to a local disk.
  3. Update the struct to be saved to the db with the list of the new, saved filepaths ie Map.update(%Struct, :images, ["c:\\filepath", "c:\\filepath"], &1)

For a single item you would just File.cp("source.path", "local.path"), which is easy enough with just one %Plug.Upload{} struct, but I struggle with writing the enum functions and iterating over each item to do things. Can anyone be of assistance?

This is not tested, as I obviously don’t have your files…

images = Enum.map(list, fn %Plug.Upload{filename: filename, path: path} -> 
  filepath = path <> filename
  local = "c:\\local_path\"
  local_filepath = local <> filename
  File.cp(filepath, local_filepath)
  local_filepath
end)

It is not clear to me what your point 3 is, but You could collect images like this.

Updated: use <> to concat string :slight_smile:

2 Likes

Thank you!
One little tweak, the path that it gives you is the actual file so there’s no need for filepath = path <> filename.
Otherwise this is exactly what I was looking for and I think I understand Enum.map a little better. I was thinking I would have to do an Enum.each as well but I see map does that for you. I really appreciate it.

map when you want a simple list of results

each when you don’t want to get the results, but are just doing it for side effects–rarer in functional-style programming, but possible, because after all you might be putting things into a db, or printing them for debugging, or… moving files into a new location

reduce when you want to collect something more complicated than a simple list of results–this one is the most general, you can (maybe should) think of the others as shorthand for common uses of reduce

3 Likes

and list comprehension, when You want to enum, filter and collect.