Elm get raw JSON string - elm

I'm trying to build a very simple app that will just output the raw JSON object from an api.
So I want a function that will take a url parameter and ideally return the JSON string.
I have the following code:
decode: String -> String
decode jsonString =
Decode.decodeString jsonString
apiResonse : String -> String
apiResonse url =
let
url = "https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=cats"
request = Http.get Decode.decodeString url
in
Http.send NewRequest request
But I'm struggling to understand the decoder part of the function. If anyone could help me that would be great.

If you just want to get the HTTP response as a string value, use Http.getString. The example you posted using Http.get assumes the result is in JSON and forces you to decode it to an Elm value.
Here is a modified example of the random cat generator code which just displays a dump of the response JSON instead of a cat picture:
getRandomGif : String -> Cmd Msg
getRandomGif topic =
let
url =
"https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=" ++ topic
in
Http.send NewGif (Http.getString url)
Here is a working example on ellie-app.com

Related

Postman - use response array as url for next get

from first request i get a list of url :
(30) ["https://pokeapi.co/api/v2/pokemon/1/", "https://pokeapi.co/api/v2/pokemon/2/", "https://pokeapi.co/api/v2/pokemon/3/", "https://pokeapi.co/api/v2/pokemon/4/", "https://pokeapi.co/api/v2/pokemon/5/", …]
i have to access to each url and find a value in the respone .
I saved the first response a var = url, the pre-requiste of the second request is : var url2 = pm.collectionVariables.get("url") , but, of course, it's using all urls..
can you help me?

Convert CachedOutputStream to a string

Convert CachedOutputStream to a string.
After upgrading camel from 2.12 to 2.23 I have a problem on my route, same code same route.
The response after calling a endpoint is of type org.apache.camel.converter.stream.CachedOutputStream
I tried to convert the CachedOutputStream to a String.
String body = exchange.getIn().getBody(String.class);
logger.info("FJA the string after caling endpoint: " + body);
I dk.bankconnect.hub.Util efter FJA efter streng er:
-0��phjA����/h`�FhI[����G<�����,�Z���f���=��Rϝ��s#���O��~#�G�t
How to convert the CachedOutputStream to a string?
I tried many different things to avoid the response to come as a stream. However, I do not succeeded.
Here is a little snippet of my route:
from("direct:sdc:webservice")
.setProperty("webservice", constant(Boolean.TRUE))
.setProperty("duration", simple("Forwarding request to ${property.datacentral} datacentral"))
.choice().when().simple("${property.Tracked} == true").bean(Util.class, "dura-tion").end()
.bean(Util.class, "tracker")
.bean(Util.class, "foer")
.to(Util.getProperty("sdc.url"))
.bean(Util.class, "efter")
.convertBodyTo(Document.class)
.setProperty("duration", simple("Receiving response from ${proper-ty.datacentral} datacentral"))
.choice().when().simple("${property.Tracked} == true").bean(Util.class, "dura-tion").end()
.bean(Util.class, "tracker")
.setProperty(SoapError.FAULT, xpath("/soapenv:Envelope/soapenv:Body/soapenv:Fault/faultstring/text()", String.class).namespace("soapenv", Namespace.SOAP))
.end();
My convertBodyTo fails, because its suddenly a stream.
Ok, very short
The response after calling a endpoint is of type org.apache.camel.converter.stream.CachedOutputStream
I tried to convert the CachedOutputStream to a String.
String body = exchange.getIn().getBody(String.class);
This is not a String that is readable, but many special characters.
Frank :-)

How to send a byte array as a part of Json with karate framework

I have an endpoint who consumes Json with 2 attributes, like
{id='12344', data=byte_array}
so I've wrote a test
Feature: submitted request
Scenario: submitted request
* def convertToBytes =
"""
function(arg) {
var StreamUtils = Java.type('my.utils.StreamUtils');
// it reads stream and convert it to a byte array
return StreamUtils.getBytes(arg);
}
"""
Given url 'http://my-server/post'
And def image = convertToBytes(read('classpath:images/image_1.jpg'));
And request {id:1, data: "#(image)"}
When method POST
Then status 200
However is got an exception form karate without much details
ERROR com.intuit.karate - http request failed: [B cannot be cast to [Ljava.lang.Object;
Any hits how to submit byte arrays as a part of Json with karate?
I don't think you can do that. Either the whole request should be binary (byte-array) or you do a multi-part request, where binary is Base64 encoded. As far as I know you can't put binary inside JSON. There is something called Binary JSON though.
EDIT: after assuming that the byte[] has to be Base64 encoded:
Background:
* url demoBaseUrl
* def Base64 = Java.type('java.util.Base64')
Scenario: json with byte-array
Given path 'echo', 'binary'
And def encoded = Base64.encoder.encodeToString('hello'.bytes);
And request { message: 'hello', data: '#(encoded)' }
When method post
Then status 200
And def expected = Base64.encoder.encodeToString('world'.bytes);
And match response == { message: 'world', data: '#(expected)' }
I just added this test to the Karate demos, and it is working fine. Here is the commit.

Get headers from http response

I am new to elm,
I have a login api which returns a JWT token in its hedears
curl http://localhost:4000/api/login?email=bob#example&password=1234
response:
HTTP/1.1 200 OK
authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXyLp0aSI6ImefP2GOWEFYWM47ig2W6nrhw
x-expires: 1499255103
content-type: text/plain; charset=utf-8
success
now Im trying to write a function that will send request and return the token from the headers in elm
authUser =
Http.send "http://localhost:4000/api/login?email=bob#example&password=1234"
how do I do this in a simple way?
In order to extract a header from a response, you will have to use Http.request along with the expectStringResponse function, which includes the full response including headers.
The expectStringResponse function takes a Http.Response a value, so we can create a function that accepts a header name and a response, then returns Ok headerValue or Err msg depending on whether the header was found:
extractHeader : String -> Http.Response String -> Result String String
extractHeader name resp =
Dict.get name resp.headers
|> Result.fromMaybe ("header " ++ name ++ " not found")
This could be used by a request builder like so:
getHeader : String -> String -> Http.Request String
getHeader name url =
Http.request
{ method = "GET"
, headers = []
, url = url
, body = Http.emptyBody
, expect = Http.expectStringResponse (extractHeader name)
, timeout = Nothing
, withCredentials = False
}
Here is an example on ellie-app.com which returns the value of content-type as an example. You can substitute "authorization" for your purposes.
May I humbly suggest you look at my elm-jwt library, and the get function there?
Jwt.get token "/api/data" dataDecoder
|> Jwt.send DataResult
JWT tokens normally need to be sent as a Authorization header and this function helps you create a Request type that can be passed to Http.send or Jwt.send

Elm, JSON decoder: How to decode an empty string?

What's the best way to handle an empty (no string at all) response?
Although the response code is 200, Elm returns an error because an empty response is not a valid JSON.
Here is my current code:
decodeAlwaysTrue : Json.Decode.Decoder Bool
decodeAlwaysTrue =
Json.Decode.succeed True
Http.send Http.defaultSettings httpConfig
|> Http.fromJson decodeAlwaysTrue
|> Task.perform FetchFail DeleteUserSuccess
EDIT1:
This a POST action so I can't use getString.
You could use the getString function from the Http module. That will give you back whatever string is returned from the HTTP request without attempting to convert is to a Json value.
If you instead need to use Http.send then you could do something like this:
Http.send Http.defaultSettings httpConfig
|> Task.perform FetchFail (always DeleteUserSuccess)
This assumes that DeleteUserSuccess is changed to be defined with no type parameter:
type Msg =
...
DeleteUserSuccess
It looks like you are never getting back a Json response so you'll probably be better using Http.getString
type Result = FetchFail Error
| DeleteUserSuccess
Http.getString address
|> Task.perform FetchFail (\s -> DeleteUserSuccess)
Since the successful get doesn't contain any information you can just ignore it and return DeleteUserSuccess regardless of the content of the string.