List is not updated in for loop

Hey guys. I’m running into a little problem I hope someone can help me.

  for chapter <- chapters do
    lessons = []
    for lesson_name <- chapter["lessons"] do
      %HTTPoison.Response{status_code: 200, body: body} = HTTPoison.get! "LESSON URL"
      case String.split(body, ~r/\n-{3,}\n/, parts: 2) do
        [frontmatter, content] ->
          {:ok, lesson} = YamlElixir.read_from_string(frontmatter)
          lesson = Map.put(lesson, "content", content)
          lessons = lessons ++ [lesson]
      end
    end
    new_chapter = %{name: chapter["name"], slug: chapter["slug"], course_id: course.id, lessons: lessons}
    Courses.create_chapter(new_chapter)
  end

This is my code. The problem that I’m facing is that the lessons list is not updated. After the case, it goes back to being a blank list. Can someone please help?

In Elixir, for is a function, and you have to reassign the return of for to lessions

lessions = 
    for lession_name <- chapter["lession"] do
        ....
    end

You should learn to use functions from Enum module instead of for

2 Likes

Your code can be rewrite like this

Enum.each(chapters, fn chapter ->
      lessons =
        Enum.reduce(chapter["lessions"], [], fn lession_name, lessions ->
          %HTTPoison.Response{status_code: 200, body: body} = HTTPoison.get!("LESSON URL")

          case String.split(body, ~r/\n-{3,}\n/, parts: 2) do
            [frontmatter, content] ->
              {:ok, lesson} = YamlElixir.read_from_string(frontmatter)
              lesson = Map.put(lesson, "content", content)
              lessons ++ [lesson]

            _ ->
              lessions
          end
        end)

      new_chapter = %{
        name: chapter["name"],
        slug: chapter["slug"],
        course_id: course.id,
        lessons: lessons
      }

      Courses.create_chapter(new_chapter)
    end)
4 Likes

Elixir’s data structures are never updated. They are immutable. If you are from the Java/C# world, consider everything in Elixir acts like strings, when you update it, you always get a modified copy. The original never changes.

4 Likes

Figured it out. The lessons variable is different inside the case and outside the case. This is why it was not updating. I used Enum.map on chapter to create lessons.

Yeah, I guess the answer here is less about immutability than about scoping in elixir.

6 Likes

Yeah, most of the time immutability is not the cause of how things work. BEAM could have mutable data, but as there is no syntaxt nor functions tu mutate data in Elixir, that wouldn’t change how our code work.