0

I am trying to call an external API (https://api.fortnox.se/3/customers/2) from an Excel on web.

The Web API I am calling returns a jason data structure such as the "Response" under "Retrieve a customer" session here: https://developer.fortnox.se/documentation/resources/customers/

Response data structure:

{
    "Customer": {
        "@url": "https://api.fortnox.se/3/customers/102",
        "Active": true,
        "Address1": "Halltorpsgatan",
        "Address2": null,
        "City": "KLIPPAN",
        "Comments": null,
        "CostCenter": null,
        "Country": "Sverige",
        "CountryCode": "SE",
        "Currency": "SEK",
        "CustomerNumber": "102",
        "DefaultDeliveryTypes": {
            "Invoice": "PRINT",
            "Offer": "PRINT",
            "Order": "PRINT"
        },
        "DefaultTemplates": {
            "CashInvoice": "DEFAULTTEMPLATE",
            "Invoice": "DEFAULTTEMPLATE",
            "Offer": "DEFAULTTEMPLATE",
            "Order": "DEFAULTTEMPLATE"
        },
        "DeliveryAddress1": null,
        "DeliveryAddress2": null,
        "DeliveryCity": null,
        "DeliveryCountry": null,
        "DeliveryCountryCode": null,
        "DeliveryFax": null,
        "DeliveryName": null,
        "DeliveryPhone1": null,
        "DeliveryPhone2": null,
        "DeliveryZipCode": null,
        "Email": "a.s@example.com",
        "EmailInvoice": "a.s@example.com",
        "EmailInvoiceBCC": "",
        "EmailInvoiceCC": "",
        "EmailOffer": "a.s@example.com",
        "EmailOfferBCC": "",
        "EmailOfferCC": "",
        "EmailOrder": "a.s@example.com",
        "EmailOrderBCC": "",
        "EmailOrderCC": "",
        "Fax": null,
        "GLN": null,
        "GLNDelivery": null,
        "InvoiceAdministrationFee": null,
        "InvoiceDiscount": null,
        "InvoiceFreight": null,
        "InvoiceRemark": "",
        "Name": "Anders Svensson",
        "OrganisationNumber": "",
        "OurReference": "",
        "Phone1": "0435-9249236",
        "Phone2": null,
        "PriceList": "A",
        "Project": "",
        "SalesAccount": null,
        "ShowPriceVATIncluded": false,
        "TermsOfDelivery": "",
        "TermsOfPayment": "",
        "Type": "PRIVATE",
        "VATNumber": "",
        "VATType": "SEVAT",
        "VisitingAddress": null,
        "VisitingCity": null,
        "VisitingCountry": null,
        "VisitingCountryCode": null,
        "VisitingZipCode": null,
        "WWW": "",
        "WayOfDelivery": "",
        "YourReference": "",
        "ZipCode": "264 32"
    }
}

Inspired by the Stackoverflow post here: Fetch error on Office Script (Excel on web) I wrote the following code:

interface aCustomer {
  Customer: CustomerClass;
}

interface CustomerClass {
  Address1: string;
  Country: string;
}

async function main(workbook: ExcelScript.Workbook): Promise<void> {
  let response = await fetch("https://api.fortnox.se/3/customers/2", {
    method: "GET",
    mode: "no-cors",
    headers: {
      "Access-Token": "XXXX",
      "Client-Secret": "XXXX",
      "Content-Type": "application/json",
      "Accept": "application/json"
    }
  });
  let customer2: aCustomer = await response.json();
  console.log(customer2);
}

But when I ran it kept throwing the error: "Line 21: Unexpected end of input"

Line 21: let customer2: Customer = await response.json()

I guess I have defined a wrong interface, or otherwise any idea what the problem might be? Thanks!

Max
  • 1
  • 1
    Does this answer your question? [fetch() unexpected end of input](https://stackoverflow.com/questions/45696999/fetch-unexpected-end-of-input) – Nishant Apr 05 '21 at 07:24
  • Type definitions are not yet a problem. I guess your data fetching has problem. Have a look at the link I mentioned – Nishant Apr 05 '21 at 07:25
  • Thanks @Nishant. Do you mean that I should not use 'no-cors' mode in the fetch() method? Though when I tried without "mode: 'no-cors' ", then it "Failed to fetch" on Line 11 "let response = await fetch("https://api.fortnox.se/3/customers/"... Any ideas how I could solve it? Thanks! – Max Apr 05 '21 at 11:48
  • @Max - did you ever get an example working? I'm struggling with this as well – swv Aug 28 '21 at 18:36

1 Answers1

0

It seems the API you're trying to use is most likely provided to be consumed by either a desktop client application or server application, but not directly from client side JavaScript within a browser (where CORS might become an issue).

A possible workaround is to use a "Fetch Proxy". In short, it is a simple web server that passes along your original requests to the target API and sends back the responses to your client side JavaScript. This could work since there won't be CORS problem between this Fetch Proxy server and the target API (server-to-server communication) and at the same time this Fetch Proxy server is configured to allow CORS from your client side JavaScript.

You can build and host your own Fetch Proxy server or you can try some existing ones. But if you care about data privacy or performance, you probably want to build and host your own. This Stack Overflow post was particularly talking about one of the existing popular Fetch Proxy server implementation ("CORS Anywhere").

And this article also has some good explanation on this CORS issue and the Fetch Proxy idea.

Yutao Huang
  • 1,334
  • 1
  • 10
  • 20