0
votes

The problem

I need to create a string interpolating a list of integers in it.

"""
SomeQuery {
  someQuery(articleIds: #{inspect article_ids}) {
    edges {
      node {
        id
      }
    }
  }
}
"""

Failing example

For example, the list [725553234] makes the example above to fail:

article_ids = [725553234]

"""
SomeQuery {
  someQuery(articleIds: #{article_ids}) {
    edges {
      node {
        id
      }
    }
  }
}
"""
** (exit) an exception was raised:
    ** (UnicodeConversionError) invalid code point 725553234
        (elixir) lib/list.ex:839: List.to_string/1
        (commsapp_api) lib/my_project/client.ex:70: CommsappApi.News.Clients.CommunicationMs.Client.articles_feed/3

System

Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Elixir 1.6.3 (compiled with OTP 20)

Tried solutions

It tried the following:

  • Using inspect is not working: articleIds: #{inspect(article_ids)}
  • Using the IO.inspect with the :char_lists opt with :as_list: IO.inspect(article_ids, char_lists: :as_lists
  • Trying to join the integer list as string with: articleIds: [#{Enum.join(article_ids, ", ")}]
  • Interpolating the integers parsed to string with: Enum.map(article_ids, &Integer.to_string/1) |> Enum.join(", ")
  • I tried using a single line instead of a multiline string, not working
  • Many things I don't remember after trying different solutions... >.<

Guesses

The problem comes when using the brackets in the string, Elixir treats the interporlation as a list and raises the error because it cannot find the codepoints.

Ideas?

Thanks in advance!

2
What's the exact output you want? And none of those things you tried worked?Dogbert
#{inspect(ids)} would probably work.Aleksei Matiushkin
@mudasobwa nope, it doesn’tqgadrian
@Dogbert none of them (and others more) didn’t work. I need to have the strong representation with the integer list to be able to make a network call using that string as a body (not using a network library in my code JFYI, it’s a third party dep the one which uses httpoison).qgadrian
Also, please confirm that article_ids = [725553234] followed by string with interpolation assignment fails in iex. Not deeply in the project code, just this: assign ids ⇒ assign interpolated string ⇒ boom.Aleksei Matiushkin

2 Answers

1
votes

In the documentation on strings, binaries and charlists, the charlists are defined as a list of point codes, i.e. integers. The code

article_ids = [725553234]
"#{article_ids}"

attempts to print the character which point code is 725553234. This point code is not defined and you get the error. Replace 725553234 by 65 and you should get an A character.

To interpolate your list of integers, you may want to do things like this:

iex(5)> a=[65, 66, 67]
'ABC'
iex(6)> "#{Enum.map(a, fn(c) -> Integer.to_string(c)<>" " end)}"
"65 66 67 "

BTW, if you look at list [65, 66, 67] is interpreted as 'ABC'.

0
votes

By using Enum.join return string and separate integer by ","

Enum.join(list, ",")

or using Enum.map return as list by changing every integer value to string

Enum.map(list, &Integer.to_string/1)

list = [1, 2, 3, 4]

Enum.join(list, ",") -> "1,2,3,4"

Enum.map(list, &Integer.to_string/1) -> ["1", "2", "3", "4"]