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.