Javascript API in print Templates

SirSquatchSirSquatch Posts: 2Member

I have read on the forums multiple instances where people have wanted to use the API in a print template in order to get additional information but no actual examples. Is there someone out there that has successfully done this? If so can you post an example?


I am able to pull items using postman and can even pull outside API information into the templates but I can't seem to query anything from lightspeed. My guess is because of the authentication but wanted to see if others have been successful. Code I've tried below, obviously the bracketed info is replaced for privacy:

<html>

<body>

<script>

var request = new XMLHttpRequest()

request.open('GET', 'https://api.lightspeedapp.com/API/Account/{{accountid}}/Item/224.json', true)

request.setRequestHeader("Authorization","{{token info}}");

request.onload = function() {

  alert("OnLoad");

 // Begin accessing JSON data here

 var data = JSON.parse(this.response)

 if (request.status >= 200 && request.status < 400) {

data.forEach(Item => {

 alert(Item.itemID)

})

 } else {

alert('error')

 }

}

request.send()

</script>

</body>

</html>

13 comments

  • Adrian SamuelAdrian Samuel Posts: 472Moderator, Lightspeed Staff moderator
    edited June 19

    Hey @SirSquatch,

    try this instead:

    (async() => {

    const request = await fetch('https://{{domain}}/API/Account/{{accountID}}/{{endpoint}}.json', {

    credentials:"same-origin"

    });

    const response = await request.json();

    console.log(response)

    })()


    Where {{domain}} could be us.merchantos.com/us.lightspeedapp.com

    the api.lightspeedapp.com is only used on the server, but since you're making requests on the client, that has to change

    and the endpoint is the specific endpoint in the API you're referencing which can be found here:

    https://developers.lightspeedhq.com/retail/authentication/authentication-overview/

    Adrian Samuel

    API Integrations Consultant - Strategic Solutions

    Lightspeed HQ

  • SirSquatchSirSquatch Posts: 2Member

    Thank you Adrian,

    Firstly I appreciate the help immensely!

    I am still seeing similar results where I get no results back. So, because I am calling this from the print template I don't need to pass an authorization header? It seems like a fairly simple call but I must be missing something easy. I'm doing a simple call to the Item API, does that look to be the correct location then?

    <script>

    (async() => {

    const request = await fetch('https://us.merchantos.com/us.lightspeedapp.com/API/Account/{{accountID}}/Item/224.json', {credentials:"same-origin"});

    const response = await request.json();

    alert(response);

    })()

    </script>

  • atheismannatheismann Posts: 9Member

    I'm having a similar issue, I am not returning any results when attempting to place this call:

    <script>


    (async() => {


    const request = await fetch('https://us.lightspeedapp.com/API/Account/{AccountID}/Item/{{ Line.Item.ItemID }}/Image.json', {credentials:"same-origin"});


    const response = await request.json();


    alert(response);


    })()


    </script>


    I'm trying to add product images to the receipt.

    Is there a particular place in the template that the API call needs to be?


    Thanks,

    Andrew

  • Adrian SamuelAdrian Samuel Posts: 472Moderator, Lightspeed Staff moderator

    Hey @SirSquatch,

    No worries, that URL is wrong, you've put two domains in one request. You need to select the one that you're logged into


    so your fetch URL should be: fetch('https://us.lightspeedapp.com/API/Account/{{accountID}}/Item/224.json',

    OR

    fetch('https://us.merchantos.com/API/Account/{{accountID}}/Item/224.json',

    Adrian Samuel

    API Integrations Consultant - Strategic Solutions

    Lightspeed HQ

  • Adrian SamuelAdrian Samuel Posts: 472Moderator, Lightspeed Staff moderator
    edited June 19

    @atheismann,

    Maybe you've got your domain wrong, it needs to match the domain you're logged in under


    if you're under us.lightspeedapp.com then you need to put that in your URL

    If you want the browser to tell you your domain, put the object: window.location.host and the browser will return the right match:

    https://developer.mozilla.org/en-US/docs/Web/API/Location


    This works for me:

     (async() => {

          const request = await fetch('https://us.merchantos.com/API/Account/{{myAccountID}}/Item/{{theItemIDOfAnItemWithAnImage}}/Image.json', 

      {credentials:"same-origin"});

      const response = await request.json();

    // I've stringified the results here because you cant log out an object in an alert box and view it otherwise

      alert(JSON.stringify(response));

      })()

    Try it out in the console first to make sure it works, then enter it into your template

     

    Adrian Samuel

    API Integrations Consultant - Strategic Solutions

    Lightspeed HQ

  • atheismannatheismann Posts: 9Member

    @Adrian Samuel

    I'm getting the response, the issue that I am having is that I cannot call the data into the template to display some of that additional data.

  • Adrian SamuelAdrian Samuel Posts: 472Moderator, Lightspeed Staff moderator

    @atheismann ,

    What errors are you getting?

    Adrian Samuel

    API Integrations Consultant - Strategic Solutions

    Lightspeed HQ

  • atheismannatheismann Posts: 9Member

    @Adrian Samuel ,

    I'm not getting any errors per say. The information just won't show up. Here is the code:

    <div class='line_description'>

    {% autoescape true %}{{ Line.Item.description|nl2br }}{% if Line.tax == 'false' or (Line.calcTax1 == 0 and Line.calcTax2 == 0) %}*{% endif %}{% endautoescape %}

    <script>

    (async() => {

    const request = await fetch('https://us.lightspeedapp.com/API/Account/{AccountID}/Item/{{ Line.Item.itemID }}/Image.json', {credentials:"same-origin"});

    const response = await request.json();

    console.log(JSON.stringify(response));

    })()

    </script>

    {{ Image.baseImageURL }}/w-225/{{ Image.publicID }}.png

    </div>

    I am trying to pull the baseImageURL and publicID from the API call. I get the response and I can see everything in the console, I just can't pull the data to the template.

    Right now I just want the string to display on the receipt (I'll modify it after I get it working)

  • Adrian SamuelAdrian Samuel Posts: 472Moderator, Lightspeed Staff moderator

    Ah, are you familiar with how to access data in an object in Javascript and how to append that data to a HTML element?

    What you've got above won't work.

    Have a look at Mozilla's documentation on how to append data to an element in HTML:

    Essentially, you'll need to assign the DOM element you're referring to as a variable and then use the browser API to assign the data accordingly.

    To access the data in the object, you'll need to navigate to the right object path

    This should help:

    https://www.w3schools.com/js/js_objects.asp

    All the code to make this happen has to be written in Javascript, it can't be part HTML and part Javascript.

    Adrian Samuel

    API Integrations Consultant - Strategic Solutions

    Lightspeed HQ

  • atheismannatheismann Posts: 9Member
    edited June 20

    @Adrian Samuel ,

    Thank you for that, I knew I was missing something.

    I was able to get the image to display properly with one item, however, on the subsequent items the src is not passing through. I'm sure it's something simple.


    Here is the code:

    <script>

    (async() => {

    const request = await fetch('https://us.lightspeedapp.com/API/Account/{accountID}/Item/{{ Line.Item.itemID }}/Image.json', {credentials:"same-origin"});

    const response = await request.json();

    document.getElementById("prodImage").src = response.Image.baseImageURL + response.Image.publicID + ".png";

    })()

    </script>


    <div class='line_description'>

    {% autoescape true %}{{ Line.Item.description|nl2br }}{% if Line.tax == 'false' or (Line.calcTax1 == 0 and Line.calcTax2 == 0) %}*{% endif %}{% endautoescape %}

    <p><img id="prodImage" width="225px"></p>

    </div>

    Post edited by atheismann on
  • Adrian SamuelAdrian Samuel Posts: 472Moderator, Lightspeed Staff moderator

    @atheismann, it's hard for me to debug something just by looking at your code. Do you have error messages, what do you mean by the fact that the src is not coming through?

    Adrian Samuel

    API Integrations Consultant - Strategic Solutions

    Lightspeed HQ

  • atheismannatheismann Posts: 9Member

    @Adrian Samuel

    Let's try this.

    There are three items on the receipt, Item 1 will display the image. This is done by calling the image via the API and using JS to define the src of the image. This is the code:

    <div class='line_description'>

    {% autoescape true %}{{ Line.Item.description|nl2br }}{% if Line.tax == 'false' or (Line.calcTax1 == 0 and Line.calcTax2 == 0) %}*{% endif %}{% endautoescape %}

    <script>

    (async() => {

    const request = await fetch('https://us.lightspeedapp.com/API/Account/{accountID}/Item/{{ Line.Item.itemID }}/Image.json', {credentials:"same-origin"});

    const response = await request.json();

    document.getElementById("prodImage").src = response.Image.baseImageURL + response.Image.publicID + ".png";

    })()

    </script>

    <p><img id="prodImage" width="125px"></p>

    </div>


    The issue is that Item 1 will display the image, but Item 2 and Item 3 do not display the image. When viewing the HTML output of the receipt, I see that Item 1 has the following img tag:

    <img id="prodImage" width="125px" src="https://res.cloudinary.com/lightspeed-retail/image/upload/fvgaomvakqfyfelfllz8.png">

    But Item 2 and Item 3 show this img tag:

    <img id="prodImage" width="125px">

    The source is not being defined for Item 2 and Item 3.

    I'm thinking it might have something to do with how the lineDescription macro works (as this code is in the macro).

    Thoughts?

  • atheismannatheismann Posts: 9Member

    Just wanted to post this update:

    All item images are working and the images show on the receipt. This is specifically for a letter size receipt. To view the code and see how it works, take a look at the repository located here:

    https://github.com/atheismann/LSRetailPrintTemplates

Sign In or Register to comment.