Working with the Canvas API in plain JS – Pt 1

With the Canvas app not supporting JQuery (unlike the web application, which does), it make sense to write all custom JS in plain Javascript so it works across both platforms. This makes sending requests to the api harder than it would be in JQuery – apparently, JQuery $ajax request already has the necessary credentials attached.

With some help from various wonderful people on the Canvas Developers forum, the code below will query the Canvas API as the logged in user and log to the console(!).

var csrfToken = getCsrfToken();
console.log('crsfToken', csrfToken);
fetch('/api/v1/conversations/unread_count',{
          method: 'GET',
          credentials: 'include',
          headers: {
               "Accept": "application/json",
               "X-CSRF-Token": csrfToken
          }
     })
     .then(status)
     .then(json)
     .then(function(data) {
          console.log(data);
     })
     .catch(function(error) {
          console.log('Request failed', error);
     }
);

/*
 * Function which returns csrf_token from cookie see: https://community.canvaslms.com/thread/22500-mobile-javascript-development
 */
function getCsrfToken() {
     var csrfRegex = new RegExp('^_csrf_token=(.*)$');
     var csrf;
     var cookies = document.cookie.split(';');
     for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i].trim(); var match = csrfRegex.exec(cookie); if (match) { csrf = decodeURIComponent(match[1]); break; } } return csrf; } /* * Function which returns a promise (and error if rejected) if response status is OK */ function status(response) { if (response.status >= 200 && response.status < 300) {
          return Promise.resolve(response)
     } else {
          return Promise.reject(new Error(response.statusText))
     }
}
/*
 * Function which returns json from response
 */
function json(response) {
     return response.json()
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Some things to note:

  • I’m using the fetch() method as I like working with promises – fingers crossed that it’ll work in the app!
  • using James Jones csrf extracting function to populate the X-CSRF-Token header;
  • using “Accept”: “application/json” to tell Canvas that we want json and it then doesn’t include the while(1) stuff (try it without to see what I mean)
  • using credentials: ‘include’ to tell fetch() to include the Cookie in the request as this is what Canvas seems to expect

The next step is to do something useful with the api – the first goal is to add next and previous buttons to pages linked to in the mobile app (currently you will only see these if you launch into a page through the app-specific Modules page).