postmanlabs / postman-app-support

Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create better APIs—faster.
https://www.postman.com
5.78k stars 837 forks source link

[Visualize]Capability to add Handlebars helpers #7373

Open Ocsidot opened 4 years ago

Ocsidot commented 4 years ago

Hello,

With the new visualize feature and the support of Handlebars inside Postman, I think it could be helpful to have the capability to register Handlebars helpers and use them.

This could be useful for example to format some string in the visualization tab like dates. It could be possible to also register the most used helpers like the ones for comparisons (a big gap in handlebars template).

This could be done by improving the pm.visulalizer


pm.visualizer.registerHelper('if', function(conditional, options) {
  if(conditional) {
    return options.fn(this);
  }
});

let template = {{#if isActive}}<div>It's wotrking</div>{{/if}};

pm.visualizer.set(template, {
    response: pm.response.json()
});
marchy commented 4 years ago

This is badly needed. Templates without any presentation logic in them are of very limited use – literally just display same values as in the JSON response.

Presumably you are using the Visualize feature because you want to make things HUMAN-readble – which means formatting, arithmetic (ie: display a number as a % of total results), sometimes conditional logic etc.

skplunkerin commented 4 years ago

I completely agree with @marchy, I really need to add some basic logic in here. Handlebars doesn't allow inline logic, only registered helpers

skplunkerin commented 4 years ago

Here's a (really bad) work-around I'm doing since Helpers aren't available.

Option 1: Display my timezone as a hover "title" attribute on the UTC timestamp field:

let template = `
<table class="table table-dark">
  <tr>
      <th>UTC Timestamp (hover for MST)</th>
  </tr>
  {{#each response}}
  <tr>
      <!-- Get the formated Time from mstTimes array, for this current index -->
      <td title="{{lookup ../mstTimes @index}}">{{timestamp}}</td>
  </tr>
  {{/each}}
</table>
`;

let mstTimes = [];
// Loop over response
for (let resp in pm.response.json()){
  // For each loop index, convert timestamp to my timezone
  mstTimes.push(new Date(Date.parse(pm.response.json()[resp]["timestamp"])).toLocaleString("en-US", {timeZone: "America/Denver"}));
}

// pass mstTimes to template
pm.visualizer.set(template, {response: pm.response.json(), mstTimes: mstTimes});

Option 2:

Another option is to customize the full response, and just pass that in with all the changes (instead of multiple variables that I'm keeping track of indexes for...) this is a better idea, do this!

eholley commented 3 years ago

Doesn't look like this ticket is getting much traction even after all of this time.

Here's the workaround I made (inspired by @skplunkerin, but adding the modified date value back into the JSON):

...

{{#each response.schedule.scheduleList}}
    <tr>
        <td>{{_schedule_start_mdt}}
        <td>{{title}}</td>
    </tr>
{{/each}}

...

let json = pm.response.json();
for (let i in json.schedule.scheduleList) {
    let startUTC = new Date(Number(json.schedule.scheduleList[i].schedule_start) * 1000);
    let startMDT = startUTC.toLocaleString("en-US", { timeZone: "America/Denver" });
    json.schedule.scheduleList[i]._schedule_start_mdt = startMDT;
};

pm.visualizer.set(template, {
    response: json
});
ghost commented 3 years ago

I needed a Handlebars Helper Pipe to format date-time from milliseconds to readable time format. I tried doing:

Handlebars.registerHelper('formatTime', function (date, format) {
        var mmnt = moment(date);
        return mmnt.format(format);
    });

I used CDN to require moment.js but it didn't help. Following @eholley's comment, this is what I did:

let responseJson = pm.response.json();
for(let log in responseJson.logs){
    responseJson.logs[log].date = new Date(responseJson.logs[log].date).toLocaleString();
}

pm.visualizer.set(template, {response:responseJson});

and here's my template:

let template = `
<!-- CSS only -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
    integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

<div class="table-responsive">
    <table class="table table-striped">
        <caption>Max Logs: {{response.maxLogs}}</caption>
        <thead class="thead-dark">
            <tr>
                <th scope="col">ip</th>
                <th scope="col">functionName</th>
                <th scope="col">message</th>
                <th scope="col">exception</th>
                <th scope="col">date</th>
                <th scope="col">data</th>
                <th scope="col">category</th>
            </tr>
        </thead>
        <tbody>
            {{#each response.logs}}
            <tr>
                <th scope="row"><small>{{ip}}</small></th>
                <td><small>{{functionName}}</small></td>
                <td><small>{{message}}</small></td>
                <td><small>{{exception}}</small></td>
                <td><small>{{date}}</small></td>
                <td><small>{{data}}</small></td>
                <td><small>{{category}}</small></td>
            </tr>
            {{else}}
            <p>No Logs</p>
            {{/each}}
        </tbody>
    </table>
</div>
`;
aksbenz commented 2 years ago

@codenirvana , @postman-support, @shamasis , @abhijitkane

Hey,

I believe adding this feature would be really helpful, and possibly quite straightforward.

Allow a 4th optional parameter "helpers" in pm.visualizer.set()

When invoking the template(context, options), just need to pass this in the "options" as { helpers: }

For example: In Postman-Test:

let helpers = {};
helpers["loud"] = function (aString) {
  return aString.toUpperCase()
}

// With new Parameter helpers:
pm.visualizer.set(template, {response: pm.response.json()}, {}, helpers);

Sample

rLitto commented 2 years ago

👍 I have problems otherwise displaying timestamps as dates in the visualizer

perbu commented 2 years ago

For those who haven't found it - it is possible to load your own copy of handlebars which isn't restricted.

https://community.postman.com/t/using-external-libraries-in-postman-and-there-by-using-custom-handlebar-helpers-in-postman-visualization/24490

(It isn't perfect, it pollutes the global scope but I got me out of a pinch).

evestraw commented 1 year ago

It would be nice if handlebars was exposed so you can access all its features.

ChuckJonas commented 5 months ago

makes it hard to deal with complex datatypes. In my case I need an IsArray method. Sad to see this hasn't gotten any traction as it would probably be straightforward to expose handlebars