Adding TypeScript to our application

The starting point for our TypeScript—pretty much as always—is our tsconfig.json file. We are going to create this to be as slimline as possible. We are going to set this particular outDir here because the creation of our project set a number of files in wwwroot. In the wwwroot/js folder, ASP.NET has already created a site.js file, so we are going to target our script to live alongside it:

{
"compileOnSave": true,
"compilerOptions": {
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"noEmitOnError": true,
"removeComments": true,
"sourceMap": true,
"target": "es2015",
"outDir": "wwwroot/js/"
},
"exclude": [
"wwwroot"
]
}

We are going to use a single method to call the Discogs API to retrieve the relevant image. We aren't going to rely on any TypeScript packages loaded from an external source to make our API call because JavaScript provides us with the fetch API, which allows us to make REST calls without any dependencies.

We start off by adding a file called discogHelper.ts, which will contain the function we are going to call from our ASP.NET application. The reason we are adding this as a TypeScript method is that we want this to run on the client, rather than on the server side. This decreases the time taken to get the initial results loaded onto the client screen because we are going to let the client fetch and asynchronously load the images for us.

The signature of our function looks like this:

const searchDiscog = (request: RequestInfo, imgId: string): Promise<void> => {
return new Promise((): void => {
}
}

The RequestInfo parameter will accept the URL of the image request on the server. This follows the fact that Discog does not return full details about a particular music title, so the album artwork is not available at this point. Instead, it returns the REST call that we have to make to retrieve the full details, which we can then parse out to retrieve the artwork. For example, Steve Vai's Passion and Warfare album information returns the ResourceUrl of the https://api.discogs.com/masters/44477 link. That becomes the URL that we pass in as our request to retrieve the full details, including the artwork.

The second parameter that we accept is the id of the img object. When we iterate over our initial search results to build the table of results, as well as add the album title, we also include a uniquely identified image, which we pass into our function. This allows us to dynamically update src when we have finished retrieving details about the album. Sometimes, this can lead to an amusing effect in the client because some albums take longer to retrieve than others, so it is entirely possible that the list of images updates out of sequence, meaning that later images are populated sooner than earlier ones. This is nothing to worry about because we are deliberately doing this to show that our client code is truly asynchronous.

If we really wanted to worry about making our images display sequentially, we would change our function to accept an array of requests and image placeholders, issue our calls, and only update the images once all the REST calls had finished.

Unsurprisingly, the fetch API uses a promise called fetch for us to make our call. This accepts the request and, optionally, a RequestInit object that allows us to pass custom settings to our call, including the HTTP verb we want to apply and any headers we want to set:

fetch(request,
{
method: 'GET',
headers: {
'authorization': 'Discogs
token=MyJEHLsbTIydAXFpGafrrphJhxJWwVhWExCynAQh',
'user-agent': 'AdvancedTypeScript3Chapter10'
}
})
Guess what? We are using the same authorization and user-agent headers here that we set in the C# code.

We have already said that the fetch API is promise-based, so we can rightly expect that the fetch call waits to complete before it returns the result. In order to get our image, we are going to perform a couple of transformations. The first transformation is to convert the response into a JSON representation:

.then(response => {
return response.json();
})

The conversion operation is asynchronous, so the next stage of our transformation can occur in its own then block as well. At this point, if all has gone well, we should have a response body. We retrieve the HTMLImageElement using the image ID that we passed into our function. If this is a valid image, then we set src to the first uri150 result we get back, which gives us the address of the 150 x 150 px image from the server:

.then(responseBody => {
const image = <HTMLImageElement>document.getElementById(imgId);
if (image) {
if (responseBody && responseBody.images &&
responseBody.images.length > 0) {
image.src = responseBody.images["0"].uri150;
}
}
})

Putting this all together, our search function looks like this:

const searchDiscog = (request: RequestInfo, imgId: string): Promise<void> => {
return new Promise((): void => {
fetch(request,
{
method: 'GET',
headers: {
'authorization': 'Discogs
token=MyJEHLsbTIydAXFpGafrrphJhxJWwVhWExCynAQh',
'user-agent': 'AdvancedTypeScript3Chapter10'
}
})
.then(response => {
return response.json();
})
.then(responseBody => {
const image = <HTMLImageElement>document.getElementById(imgId);
if (image) {
if (responseBody && responseBody.images &&
responseBody.images.length > 0) {
image.src = responseBody.images["0"].uri150;
}
}
}).catch(x => {
console.log(x);
});
});
}
Discogs allows us to issue JSONP requests, which means that we have to pass a callback query string parameter. In order to issue a JSONP request, we would have to install the Fetch JSONP package from https://github.com/camsong/fetch-jsonp. This requires changing the signature of the fetch call to fetchJsonp instead. Apart from that, the rest of our functions look the same.

By now, we should be comfortable with the use of async/await inside promises. If we wanted a slightly less verbose function, we could change the code to this:

const searchDiscog = (request: RequestInfo, imgId: string): Promise<void> => {
return new Promise(async (): void => {
try
{
const response = await fetch(request,
{
method: 'GET',
headers: {
'authorization': 'Discogs
token=MyJEHLsbTIydAXFpGafrrphJhxJWwVhWExCynAQh',
'user-agent': 'AdvancedTypeScript3Chapter10'
}
});
const responseBody = await response.json();
const image = <HTMLImageElement>document.getElementById(imgId);
if (image) {
if (responseBody && responseBody.images &&
responseBody.images.length > 0) {
image.src = responseBody.images["0"].uri150;
}
}
}
catch(ex) {
console.log(ex);
}
});
}

In the next section, we are going to address how we call our TypeScript functionality from ASP.NET.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.253.221