Installation
To install this module you simply copy the command found on the right of this UI if your viewing this through npmjs.com. If your not, then you can use the following command to install it on your project:
npm i @jworkman-fs/asl
Loading
This NPM module will be utilized for Advanced Server-side Languages course offered by FS University (course code: WDV442). This module contains all of the methods, class, model, and data definitions already defined for all students. This module will be used for weeks 2 through 4.
Here are two different examples on how to load in the Pager class from the asl package.
Method 1
Importing entire library into one constant for later usage.
const asl = require('@jworkman-fs/asl')
const pager = new asl.Pager(...)
Method 2
Only referencing specific imports you need through object destructuring.
const { Pager } = require('@jworkman-fs/asl')
const pager = new Pager(...)
Exported Classes
Below is a list of exported class definitions that can be used in your application throughout the remainder of your time in this class.
ContactModel -> self
This class will be your go to object to query objects from. Note that this class pulls from a list of contacts defined directly inside this module. So you won't have to define your own contact data. With that said. There is no database persistance. So the data will reset itself each time your server process restarts.
Below are a few code examples of how to query contacts using this model class in your API controller.
Load all contacts in list
const all = ContactModel.index()
id
Load a single contact by its // We need to import our exceptions defined in our module
const {
ContactNotFoundError,
ContactResourceError,
ApiError
} = require('jworkman-fs/asl')
// Wrap this all in one big try/catch block
try {
// Attempt to fetch the contact with an id of "11"
const all = ContactModel.show(11)
} catch(e) {
// Using a switch case to help us route our
// exceptions & errors to their relative status codes
switch(e.name) {
// In case it's not found
case ContactNotFoundError.name:
res.status(404)
break;
// In case something really bad happened
case ContactResourceError:
case ApiError:
res.status(e.statusCode)
break;
}
// Lastely don't forget to send the exception message
res.json({ message: e.message })
}
Create a new contact
try {
// Create a new contact with some data
ContactModel.create({
fname: "Shae",
lname: "Marquise",
phone: "555-555-5555",
birthday: "1968-01-24",
email: "smarquise@gmail.com"
})
} catch(error) {...}
id
Update a contact by its try {
// Update the contact's firstname with an id of "11"
const all = ContactModel.update(11, { fname: 'Shae' })
} catch(error) {...}
id
Delete a contact by its try {
// Remove the contact with an id of "11"
ContactModel.remove(11)
} catch(error) {...}
class Pager() -> self
This class will be used on your week two assignment in order to add pagination logic to your RESTful api resource. Once a new instance is instantiated from it, it will return a few different important details about the current page context. It will automatically calculate all of the details of the page context that you will need in order to properly integrate pagination into your controller's index method.
Creating an Instance
// Import method 2: using object destructuring
const { Pager } = require('@jworkman-fs/asl')
// Building an instance with arguments (replace with actual arguments)
const pager = new Pager( ...args )
Using The Instance
Get the next, and previous page numbers from our pager context
const nextPageNumber = pager.next()
const prevPageNumber = pager.prev()
Get the total number of results left on the last page of the result set
const { left } = pager
Translate an offset from the pager context
const offset = pager.offset()
// This would be something like 0 for page 1, or 10 for page 2
// assuming the limit of the pager context was set to 10
console.log(offset)
Get the total number of pages
const { pages } = pager
Grab the total number of results
const { total } = pager
Get the current page number being used to calculate the result set
const { page } = pager
Get the final set of in view results from the pager context
const results = pager.results()
response.status(200).json(results)
Exceptions
This module relies soley on "try/catch" exception blocks to properly handle errors. What that means is that you won't be able to tell if calling a function resulted in an error based on the returned value. Instead you will need to wrap all code that references any of the code in this module inside a "try/catch" block in order to catch a wide range of exceptions, or issues that might be thrown during runtime.
Using error exceptions offers developers a much cleaner approach to handling success & errors versus relying on returned values to determine if an algorithm was executed successful or resulted in an error. It also allows a developer to map/route many different possible errors to different places depending on what exception is being thrown.
Take the following example where we try to catch exceptions thrown by our Pager class.
const {
PagerError,
PagerNoResultsError,
PagerOutOfRangeError
}
try {
// Paginates the "data" array. Sets the page to "1", and sets "10" results per page
const pager = new Pager( data, 1, 10 )
// Grabs the current page results based on the calculated pager context
const results = pager.results()
} catch(error) {
switch(typeof error) {
case "PagerError":
res.status(500).json(e.message)
case "PageOutOfRangeError":
res.status(error.statusCode).json(e.message)
default:
res.status(500).json(`Sorry, something went wrong.`)
}
}
- PagerNoResultsError - This exception/error gets thrown when there are no results to display. This shouldn't be treated as an error on the front-end. Instead it should simply return a 2xx status message back to the client, but just leave the results as an empty array.
- PagerOutOfRangeError - This exception gets thrown when the client/user has requested a page number that is outside the range of valid page numbers. For example. The client requests page number 10, but there are only 3 pages in total.
- PagerError - All of the other pagination based exceptions inherit from this one. This is considered a generic, or base exception. So in this case it could be either a PagerNoResultsError or PagerOutOfRangeError since both exceptions share this same parent.
filterContacts( data, by, op, val ) -> Contact[]
- data (array) - Array of all the contacts that you want to reduce, or apply the filter to.
- by (enum) - An enum containing the field you want to filter your contacts by. Since this value is considered an enum it can only be set to either id, fname, lname, email, phone, or birthday.
- op (enum) - An enum containing the comparison operator when applying a filter. This can only be set to either "eq", "gt", "gte", "lt", or "lte". They all get translated to "===", ">", ">=" and so on.
- val (any) - The value that the "by" argument should be compared to.
Exceptions
The follwoing list contains all of the exceptions that are used by the filterContacts()
function. Remember to wrap your filterContacts()
call inside a try/catch
block to handle any errors, or exceptions.
-
NoContactsFoundError - This exception gets thrown when
filterContacts()
has determined that no results were left after filtering was applied. Basically this gets thrown when "No search results were found." -
InvalidContactSchemaError - This exception gets thrown when
filterContacts()
the enum for the "by" argument was violated. A non existent contact field was provided to the function.
sortContacts( data, by, direction ) -> Contact[]
- data (array) - Array of all the contacts that you want to sort by.
- by (enum) - An enum containing the field you want to sort your contacts by. Since this value is considered an enum it can only be set to either id, fname, lname, email, phone, or birthday.
- direction (enum) - The direction that sorting will be done in either ascending order, or descending order. This enum can only be set to "asc", or "desc"
Exceptions
The follwoing list contains all of the exceptions that are used by the filterContacts()
function. Remember to wrap your filterContacts()
call inside a try/catch
block to handle any errors, or exceptions.
-
NoContactsFoundError - This exception gets thrown when
filterContacts()
has determined that no results were left after filtering was applied. Basically this gets thrown when "No search results were found." -
InvalidContactSchemaError - This exception gets thrown when
filterContacts()
the enum for the "by" argument was violated. A non existent contact field was provided to the function.