218 words, 2 min read

I've written my own personal RSS Reader using Elixir Phoenix.

One of the features I've wanted was to be able to import OPML files which contain lists of feeds.

I wanted an easy way to track how many items were actually import (given that the source URL in the database is having a unique index on it).

This is the original code that does the import, but doesn't count how many were actually imported:

defmodule RssReader.Feeds.OpmlImport do
  alias RssReader.Feeds.Sources

  def import(file_content, folder_id) do
    {:ok, data} = Opml.parse(file_content)

    data["body"]["outlines"]
    |> Enum.each(fn outline ->
      Sources.create_source(%{
        name: outline["text"],
        source_url: outline["xmlUrl"],
        web_url: outline["htmlUrl"],
        folder_id: folder_id
      })
    end)
  end
end

To accurately count only the successful creations (i.e., where create_source/1 returns {:ok, _}), we can tweak the pipeline a bit:

def import(file_content, folder_id) do
  {:ok, data} = Opml.parse(file_content)

  successes =
    data["body"]["outlines"]
    |> Enum.map(fn outline ->
      Sources.create_source(%{
        name: outline["text"],
        source_url: outline["xmlUrl"],
        web_url: outline["htmlUrl"],
        folder_id: folder_id
      })
    end)
    |> Enum.filter(fn
      {:ok, _} -> true
      _ -> false
    end)
    |> Enum.count()

  successes
end

What it does is:

  • Enum.map/2 captures the result of each create_source/1 call.
  • Enum.filter/2 keeps only the {:ok, _} tuples (indicating success).
  • Enum.count/1 returns the final count.

This approach gives us a reliable count of successfully created sources, making it easier to log, show user feedback, or trigger additional logic based on actual results.