If you've followed the self-learning resources, now you're ready to check your knowledge with these exercises.

  • Create a component “display-value” that displays a number. The number will come from a property.
  • Place this component in a basic web page with the value set to 10.
  • Verify that it works.
  • Write some javascript that sets a MYVALUE global variable to 11 and sets the attribute on the component.
  • Verify that you see 11 rather than 10.
  • Create a component “change-value” that has two buttons “-“ and “+”.
  • When a button is pressed, it should trigger a ”change” event containing detail “-“ or “+”.

    Hint: define an exported interface

e.g.

export interface ChangeEvent {
direction: string;
}
  • You can monitor for the button being clicked in your component using code like:
@click=${this.downClick}
  • And within your downClick function,
const event = new CustomEvent<ChangeEvent>("change", {
detail: {
direction: "-"
}
});
this.dispatchEvent(event);
  • Add this to your web page and specify a class “myclass” on it that you can refer to later.
  • Add a listener for the component’s event in your page’s javascript:
// A bit like this – which allows for there being more than one occurrence of the component/class
// alternatively you could use .getElementById without a for loop:
var el = document.getElementsByClassName("myclass");
for(i=0;i<el.length;i++) {
el[i].addEventListener("change", (evt) => {
// do something with evt.detail.direction;
});
}
  • This listener should either increment or decrement MYVALUE depending on the event’s detail.
  • Update display-value accordingly.
  • Verify that this works.
  • Modify “change-value” to also have a “Reset” button.
  • This should trigger a different event “reset”. This does not need to pass any value.
  • Add a listener for the new event in javascript.
  • The listener must reset MYVALUE to 0 and update display-value accordingly
  • Verify that the additional button works.
  • Put a <div> around your components on the page
  • Add a new <div> containing two ordinary buttons to the top of your web page: “Hide” and “Show”.
  • When the Hide button is clicked, hide the components.
  • When the Show button is clicked, show the components.
  • Verify that these work.

    Hint: Create a class in your CSS for hiding content and apply/remove this class to the components’ div as appropriate.

APIs are accessed asynchronously using the “fetch” function. When we have the response, a “callback” function is automatically invoked.

  • You will need to run a cors proxy to prevent Chrome from refusing to hit APIs from a different source from the web site. ( \\europe\uk\admin\CSA\cors-cache-proxy.zip - unzip and do “npm start”) *Take a look at the Pricing project ( \\europe\uk\admin\CSA\Pricing_yyyymmdd_hhmm.zip ) to see functions in Pricing.js: asyncGetAPI getProducts ** getProductsCallback – processes the response into a UUX combo box
  • Create your own functions which will get the list of products and simply store the response.
  • Use console.log(your-response) to see the response.
  • Note that the response is a JSON object which JavaScript can easily navigate. (you can JSON.stringify to convert to a string and you can JSON.parse to convert a string into a JSON object)
  • Add a button to the page that invokes the API on demand.
  • Verify that this works.
  • Create a new “product-list” component that will accept the API response as a property and display the list of product names.
  • You will need to use javascript “object.map” method to render a list of array elements – see the Pricing project’s quotation-component.ts, renderQuotation function
  • Amend your callback routine to pass the response to the new component
  • The component should protect itself from null/empty properties, perhaps rendering a simple message if there is no data.
  • Verify that this works.
  • Modify your “product-list” component to take an additional property “loading”. If this has the value ‘true’, simply render ‘Loading…’ If not, render as normal.
  • Modify your javascript to set the loading attribute to ‘true’ just before requesting the API, and to ‘false’ in the callback function.
  • Verify that this works (you may need to insert a deliberate pause or use console.log to verify if the API is performing quickly).