Public
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Not applicable

Getting an API V1 call into JSON I can use in Javascript?

I want to get a V1 API call back in a format that I can use as JSON in Javascript in a component. How do I do that? For example:

(/categories/id/categoryName/labels)

<#assign someLabels = restadmin("/${context}/id/${contextId}/labels?restapi.response_format=json").labels.label?sort_by("text")/>
<script>
let someVar = [${someLabels}];
</script>

I know that V2 has the apiv2.toJson() method, but in this case V1 is the only way I know of to get a list of labels from a category, for example. 

20 Replies 20
Champion

@Inactive User  - You could use the restapi.response_format parameter to return JSON:

 

restapi.response_format=json

 

For more details see developer docs.

 

Alternatively, you can move your API requests to an endpoint and build a custom JSON response for that endpoint. Afterwards you can request your endpoint from your JS code.

Not applicable

@cike Thanks, however, I'm still unable to feed that directly into JS. To wit:

 

<#-- EX: https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels -->
<#assign someLabels = restadmind("/${context}/id/${contextId}/labels?restapi.response_format=json") />

<script>
console.log('script');
let labels = [${someLabels}];

console.log('labels',labels);
</script>

Gets me a freemarker error => 


Screen Shot 2019-07-09 at 9.09.27 AM.png

 

How would creating an endpoint for this make that result any different?

@Inactive User  - I think you have two errors in your REST call:

 

Firstly, you need to check your APIv1 request. I think you need to add an additional "/labels" path parameter to get a list of labels for your category:

 

<#-- APIv1 request: <a href="https://community-stage.jmp.com/restapi/vc/categories/id/[id]/labels/labels" target="_blank">https://community-stage.jmp.com/restapi/vc/categories/id/[id]/labels/labels</a> -->

<#assign someLabels = restadmind("/${context}/id/${contextId}/labels/labels?restapi.response_format=json") />

 

Take a look into the developers docs and APIv1 reference.

 

Secondly, to access the labels from the API response you need to access the labels object of the response. Your request will return something similar the example below:

 

{
  "response": {
    "status": "success",
    "labels": {
      "label": [
        {
          "type": "label",
          "href": "/labels/id/1985",
          "text": {
            "type": "string",
            "$": "Festnetz | Internet | Fernsehen"
          },
          "id": {
            "type": "int",
            "$": 1985
          }
        },
        {
          "type": "label",
          "href": "/labels/id/1982",
          "text": {
            "type": "string",
            "$": "Sonstiges"
          },
          "id": {
            "type": "int",
            "$": 1982
          }
        },
      }
    ]
  }
}

 

 

The have access to the label values, you have to access your Freemarker variable like this:

 

<#assign labels = someLabels.labels.label />

 

 

Be aware to add checks for empty responses or lists. Otherwise you will get Freemarker errors for accessing non-existing objects.

Not applicable

Will try that out, thanks. Then I can assign it to a JS variable like so?

var labels = [${labels}]

@Inactive User  - You'll need to wrap your Freemarker variable in "", because Javascript can't handle ${labels} and will run into errors.

While the Freemarker JSON response should be valid you could parse the response with JSON.parse:

var labels = JSON.parse('${labels}')

 

Not applicable

Thanks, but I can't seem to get this to work no matter what I do:

 

Here's the JSON output from the call directly from the browser: 

<a href="https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels/labels?restapi.response_format=json" target="_blank">https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels/labels?restapi.response_format=json</a> 

OUTPUT: 

{
  "response": {
    "status": "success",
    "labels": {
      "label": [
        {
          "type": "label",
          "href": "\/labels\/id\/55",
          "id": {
            "type": "int",
            "$": 55
          },
          "text": {
            "type": "string",
            "$": "Data Access and Manipulation"
          }
        },
        {
          "type": "label",
          "href": "\/labels\/id\/28",
          "id": {
            "type": "int",
            "$": 28
          },
          "text": {
            "type": "string",
            "$": "Data Exploration"
          }
        }
      ]
    }
  }
}

 

RELEVANT ENDPOINT CODE:

<#assign contextId = 'discovery'/>
<#assign context = 'categories'/>

<#-- MAIN LABELS -->
<#-- EX: <a href="https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels" target="_blank">https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels</a> -->
<#assign someLabels = restadmin("/${context}/id/${contextId}/labels/labels?restapi.response_format=json") />

var labels = JSON.parse('${someLabels}');
console.log('labels',labels);

 

Output, same Screen Shot 2019-07-10 at 11.03.01 AM.pngFreemarker Error: 

 

 

The error occurs, because you try to access the complete response object. But this is not supported.

The first element of the response you're able to access is the label array:

...
label: [
 ...
 ...
]

 

To solve the error, just add .labels.label to your code:

var labels = JSON.parse('${someLabels.labels.label}');

 

The keep your Javascript code as clean as possible, you could also add the .labels.label part to your Rest request:

<#assign someLabels = restadmin("/${context}/id/${contextId}/labels/labels?restapi.response_format=json").labels.label />

 

Not applicable

Sadly, this still throws the same error.

It would seem it should be easier than this to get something that's supposedly returned in JSON to initialize a JS variable with it...

<#assign contextId = 'discovery'/>
<#assign context = 'categories'/>

<#-- MAIN LABELS -->
<#-- EX: <a href="https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels" target="_blank">https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels</a> -->
<#assign someLabels = restadmin("/categories/id/discovery/labels/labels?restapi.response_format=json").labels.label />
  

  var labels = JSON.parse('${someLabels.labels.label}');
  console.log('labels',labels);
  

Screen Shot 2019-07-11 at 9.17.55 AM.png

You must not add the .labels.label part in both locations. Just one is needed. I recommend the following:

<#assign contextId = 'discovery'/>
<#assign context = 'categories'/>

<#-- MAIN LABELS -->
<#-- EX: <a href="https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels" target="_blank">https://community-stage.jmp.com/restapi/v1/categories/id/discovery/labels</a> -->
<#assign someLabels = restadmin("/categories/id/discovery/labels/labels?restapi.response_format=json").labels.label />
  

  var labels = JSON.parse('${someLabels}');
  console.log('labels',labels);

 

Additionally, don't forget to wrap your Javascript in a <script> tag or Khoros' <liaAddScript> directive.

Not applicable

That didn't seem to make any difference either. 

<#assign someLabels = restadmin("/categories/id/discovery/labels/labels?restapi.response_format=json").labels.label />
  
<script>
  var labels = JSON.parse('${someLabels}');
  console.log('labels',labels);
  </script>

Same error. 

No idea why this isn't working; I've opened a ticket with Khoros on it but thanks for the help. I'll update this thread when I get a reply from them. 

@Inactive User  - You could check if your request results in a non-empty list of labels:

<#if someLabels?? && someLabels?size gt 0>
  <#-- Print ${someLabels?size} here -->

  <#list someLabels as label>
    <#-- Print ${label.text} here -->
  </#list>
</#if>

Or you simple test your request through the browser or via other tools (curl, Postman).

Is it still the line

var labels = JSON.parse('${someLabels}');

which causes the error?

Not applicable

It's still the line JSON.parse() that's giving me the issue. And ${label.text} won't print because it's not actually a text node, it's an object, "$" has the text ... whew. Too confusing. Thanks tho.

The "$" sign shouldn't bother you. You can access the text or id value of labels as I mentioned. Freemarker handles this for you.

Did you try the snippet I provided to test your someLabels variable?

If this snippet works and will print some data, you can be sure your request/response is correct and there are maybe some limitations on accessing the object as you tried in your JS code.

Not applicable

I did use the snippet but it didn't print anything. When I removed the comment marks, did print in the enpdoint. Still can't get it into JS tho.

@Inactive User  - Maybe we should go a step back and see if I understand your scenario in the right way 😊

You fetch labels of a node in an endpoint and want to access them via JS from a custom component, is that correct?

If so, I recommend the following:

  1. Fetch and process labels in the endpoint as you want and let the endpoint return JSON.
  2. Use JS in a custom component to request your endpoint and handle your response ( = the labels) from there on.

 

If I'm wrong, it would be great if you could describe your intention, so I can figure out how to go on. 🙂

Not applicable

@cike  Thanks, yes, that is correct. 

However, the issue is that I can't get the endpoint to show up in JSON? If it's not JSON in the endpoint itself, how am I going to call that in a component and expect JSON? That make sense? Thanks 🙂

I guess the question is then, "how do I get an endpoint to return JSON"?

@Inactive User  - Ok. Good to know that you want your endpoint to return JSON which than can be requested by your components.

You could use something like this to build your endpoint:

 

<#attempt>
  <#assign someLabels = restadmin("/categories/id/discovery/labels? restapi.response_format=json").labels.label />

  <#if someLabels?? && someLabels?size gt 0>
    {
      "response": {
         "status": "successful",
         "labels" : [
           <#list someLabels as label>
             "${label.text}"<#if (label?has_next)>,
           </#list>
         ]
       }
    }
  <#else>
    {
      "response": {
        "status": "empty"
      }
    }
  
<#recover>
  {
    "response": {
      "status": "error",
      "message": "${.error?json_string}",
      "query" : "${queryMsg?json_string}"
    }
  }

 

 

This should always return a JSON object from your endpoint. You should test your endpoint by directly accessing its Url, to see if things work as expected.

Not applicable

 Thanks! I just added a few things to it to get it to work 100%:

 

<#attempt>
    <#assign someLabels = restadmin("/categories/id/discovery/labels?restapi.response_format=json").labels.label />

    <#if someLabels?? && someLabels?size gt 0>
        {
        "response": {
        "status": "successful",
        "labels" : [
        <#list someLabels as label>
            {"id":"${label.id}","text":"${label.text}"}<#if (label?has_next)>,
        
        ]
        }
        }
    <#else>
        {
        "response": {
        "status": "empty"
        }
        }
    
    <#recover>
        {
        "response": {
        "status": "error",
        "message": "${.error?json_string}",
        "query" : "${queryMsg?json_string}"
        }
        }


Great!

Hope everything works as you want, now. Requesting the endpoint via AJAX from a component shouldn't be that difficult from this point. 🙂

Not applicable

Thanks for all your help. Shouldn't have been that hard to begin with but ... some things are just a pain in Khoros Community... Thanks

Welcome to the Technology board!

Curious about our platform? Looking to connect on social technology? You've come to the right place!

Are you a Khoros customer? For direct assistance from our Support team, please visit the Support Forum.