Reputation: 31526
I am reading this tutorial https://www.stackbuilders.com/blog/nonsense-getting-started-with-reason-and-reason-react/. One of the problems I am facing is that api.noopschallenge.com
is now dead. I replaced the API call to this https://random-word-api.herokuapp.com/word?number=20
This works but returns a Json Array. I have to convert the Json Array to list(string).
I modified the decodeWords
function as
let decodeWord = (json: Js.Json.t) : list(string) =>
switch(Js.Json.decodeArray(json)) {
| None => []
| Some(array) => Belt.Array.map(Js.Json.decodeString, array)
};
But this gives me error
This has type: Js.Json.t => option(Js.String.t) But somewhere wanted: array('a)
How do I convert the Json Array to list(string)
?
Upvotes: 0
Views: 165
Reputation: 29106
Two problems:
Belt.Array.map
around.´array` should come first.decodeString
returns an option(string)
instead of just a string
, you'll have to deal with the None
s somehow. Using Belt.Array.keepMap
is a shorter way of just ignoring them.let decodeWords = (json: Js.Json.t): list(string) =>
switch (Js.Json.decodeArray(json)) {
| None => []
| Some(array) =>
array->Belt.Array.keepMap(Js.Json.decodeString)->Belt.List.fromArray
};
But using the Js.Json
API directly is rather cumbersome. You might want to consider using a third-party json decoding library such as bs-json
(disclaimer: authored by me) instead. Then it would be as simple as:
let decodeWords = Json.Decode.(list(string))
Or, if you still want it to return an empty list instead of raising an exception on decode failure:
let decodeWords = Json.Decode.(withDefault([], list(string)))
Upvotes: 1
Reputation: 31526
I think I resolved it myself. but if you know of a better solution then please let me know
let decodeWords = (json: Js.Json.t) : list(string) =>
switch(Js.Json.decodeArray(json)) {
| None => []
| Some(array) => Belt.Array.reduce(array, [], (acc, value) => {
switch(Js.Json.decodeString(value)) {
| None => acc
| Some(v) => [v, ...acc]
}
})
};
Upvotes: 0