How do I get the length of a [Nat8]?

Getting

field length does not exist in type
  [Nat8]

How do I get the length of a Nat8 array?

Similarly, I’m seeing

type field status does not exist in type
  {body : [Nat8]; headers : [HttpHeader]; status : Nat}

Why does it say it doesn’t exist if it’s showing it right there?

You can get the size of any array by using the size() function.

let my_array : [Nat8] = [0, 2, 255];

my_array.size()  ->  3 : Nat

Thank you. Do you know what’s going on with the .status part?

Is there a Motoko syntax cheatsheet or something like that?

That’s a bit confusing. Not sure I understand either.

Can you provide any more context about your code?

It just fixed itself when I fixed another error higher up. :woman_shrugging:

My main problem seems to be I don’t know where to look for basic Motoko syntax.

For example, I need to initialise a Char type now and I don’t know how to type that.

This doesn’t work:
var decoded_char : Char;

But beyond the answer to that question, what documentation I can refer to to find that kind of basic syntax answer in the future?

1 Like

I’m also trying to convert a Nat8 to a Nat32, that sort of thing.

1 Like

We’re currently reworking the Motoko docs exactly because it’s hard to find basic syntax. The three places I usually use to figure stuff out are:

that would be in the reference

2 Likes

It resurfaced:

I’ll tell you my real problem first in case there is a better solution:

I’m using this code to get an http response back: motoko-outcalls-proxy/main.mo at main · krpeacock/motoko-outcalls-proxy · GitHub

It works fine, but the body of the response seems to be ASCII encoded: on CandidUI, on calling proxy("https://official-joke-api.appspot.com/random_joke") I’m getting:

(record {status=200; body=vec {123; 34; 105; 100; 34; 58; 51; 48; 53; 44; 34; 116; 121; 112; 101; 34; 58; 34; 103; 101; 110; 101; 114; 97; 108; 34; 44; 34; 115; 101; 116; 117; 112; 34; 58; 34; 87; 104; 101; 114; 101; 32; 100; 111; 101; 115; 32; 70; 111; 110; 122; 105; 101; 32; 108; 105; 107; 101; 32; 116; 111; 32; 103; 111; 32; 102; 111; 114; 32; 108; 117; 110; 99; 104; 63; 34; 44; 34; 112; 117; 110; 99; 104; 108; 105; 110; 101; 34; 58; 34; 67; 104; 105; 99; 107; 45; 70; 105; 108; 45; 69; 121; 121; 121; 121; 121; 121; 121; 121; 46; 34; 125}; headers=vec {record {value="default-src 'self'"; name="Content-Security-Policy"}; record {value="strict-origin"; name="Referrer-Policy"}; record {value="geolocation=(self)"; name="Permissions-Policy"}; record {value="max-age=63072000"; name="Strict-Transport-Security"}; record {value="DENY"; name="X-Frame-Options"}; record {value="nosniff"; name="X-Content-Type-Options"}}})

Whereas on the browser I get:

// 20221214111907
// https://official-joke-api.appspot.com/random_joke

{
  "id": 208,
  "type": "general",
  "setup": "What do you call a cow with two legs?",
  "punchline": "Lean beef."
}

So I’m creating a whole other function to try and iterate through the body and convert it to text and return the same response but with a readable body.

Is there a simple way to get normal text json back?

If not, this is the function I wrote to try and decode it:

public func http_call_and_decode(url : Text) : async Types.CanisterHttpResponsePayloadDecoded {
    let response_from_proxy : Types.CanisterHttpResponsePayload = await proxy(url);

    var decoded_body = "";
    var decoded_char : Char = Char.fromNat32(0);
    var nat_8_char : Nat8 = 0;
    var nat_char : Nat = 0;
    var nat_32_char : Nat32 = 0;
    for (i in Iter.range(0, response_from_proxy.body.size())) {
      nat_8_char := response_from_proxy.body[i];
      nat_char := Nat8.toNat(nat_8_char);
      nat_32_char := Nat32.fromNat(nat_char);

      decoded_char := Char.fromNat32(nat_32_char);
      decoded_body := Text.concat(decoded_body, Text.fromChar(decoded_char));
    };

    let response_decoded : Types.CanisterHttpResponsePayloadDecoded = {
      status : response_from_proxy.status;
      body : decoded_body;
      headers : response_from_proxy.headers;
    };

    response_decoded;

  };

And that’s where I’m getting

type field status does not exist in type
  {body : [Nat8]; headers : [HttpHeader]; status : Nat}

on the second line here:

let response_decoded : Types.CanisterHttpResponsePayloadDecoded = {
      status : response_from_proxy.status;
      body : decoded_body;
      headers : response_from_proxy.headers;
    };

I added this type to Types.mo, in addition to the ones seen on the repo above:

  public type CanisterHttpResponsePayloadDecoded = {
        status : Nat;
        headers : [HttpHeader];
        body : Text;
    };

Found the culprit. Syntax again:

let response_decoded : Types.CanisterHttpResponsePayloadDecoded = {
      status = response_from_proxy.status;
      body = decoded_body;
      headers = response_from_proxy.headers;
    };

instead of

let response_decoded : Types.CanisterHttpResponsePayloadDecoded = {
      status : response_from_proxy.status;
      body : decoded_body;
      headers : response_from_proxy.headers;
    };
2 Likes