You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.9 KiB

Lesson Objectives

  1. Completed angular_create.md
  2. Create a function to get all holidays
  3. On page load, show all holidays
  4. After creating a new holiday, refresh list of holidays

Create a function to get all holidays

  • We'll need to make a new request to get our list of all of our holidays

  • Again, we'll make a new function that calls the $http() function

  • We'll pass the $http() function an object with the following

    • method : GET
    • url : /holdays Unlike our POST request, we don't need to include data because we're not sending any data for this get request.
  • Our $http() function again, will have a .then() function chained to it, that will wait for the response from the http request and then give us access to that data

In js/app.js

this.getHolidays = () => {
  $http({
    method: 'GET',
    url: '/holidays'
  }).then(response => {
    this.holidays = response.data
  }, error => {
    console.log(error)
  })
}

If we make our changes and reload the page, we shouldn't see anything happen, no console.log of our data.

That's because we've only defined our function and not called it.

Call the getHolidays function

We were able to call createHoliday because clicking on the create new holiday button listened for a click and then triggered this function.

In this case, we just want to immediately load our data on page load. To do this, we just invoke the function after the function has been defined.

this.getHolidays = () => {
  $http({
    method: 'GET',
    url: '/holidays'
  }).then(response => {
    console.log(response.data)
  }, error => {
    console.log(error)
  })
}

// load immediately on page
this.getHolidays()

Ok, so we are able to console.log on page load, which is cool, but we'd really like to update the browser view.

console.log data on page load

Render our Holidays in the Browser

With Angular's two-way data binding, we're going to have to declare a variable that is going to hold our data both in index.html and app.js

  • both the index.html and the app.js will need to have this variable
  • let's name our variable holidays

In index.html

  • in our index.html the holidays variable will be accessible by adding ctrl. in front of it. We decided that it should be ctrl in our body tag right at the ng-controller="MainController as ctrl"
  • so any time we want to access it in the html we need to follow two rules
  • We are accessing it in a tag that is nested inside the body tag.
  • We are putting ctrl. in front of it
  • therefore our variable in index.html is ctrl.holidays

In js/app.js

  • We can give our index.html access to our holidays variable by doing the following
  • making sure we are in the correct controller. In our case, we just have one main controller: MainController, so we have to make sure we are accessing our variable inside of it
  • put this. in front of our variable, so our variable inside app.js inside the MainController is this.holidays

Recap

  • It HAS to be holidays in both the index.html and app.js

  • in index.html it is referenced by ctrl.holidays

  • in app.js it is referenced by this.holidays

  • changing the value in one 'place' will update the value in the other

  • First we are going to set our response data to this.holidays

In js/app.js

this.getHolidays = () => {
  $http({
    method: 'GET',
    url: '/holidays'
  }).then(response => {
    this.holidays = response.data
  }, error => {
    console.log(error)
  })
}
  • Next let's use ng-repeat to display our holiday names inside a table cell td tag
  • ctrl.holidays is an array of objects
  • we have to set a variable name for one holiday object, we do that with angular by writing holiday in ctrl.holidays - that sets a variable name of holiday for each object in the holidays array
  • For now, all we want to do is see the holiday name. So we'll have to access that property out of our holiday objects by doing holiday.name

In index.html

  </form><!-- closes our create form -->
  <table>
    <tr ng-repeat="holiday in ctrl.holidays">
      <td> {{ holiday.name }} Day</td>
    </tr>
  <table>
</div><!-- closes div with class container -->

Success looks like this index route displaying in browser

Update the List of Holidays When a New Holiday is Created

Let's add a new holiday

  • We know it works because we are still console.logging the response create holiday response

  • But we don't see our page update it

  • Let's refresh our page, ok we see it now, but that's not great user experience for a user to have to know to refresh the page to see their change.

  • What we really want is that upon a successful response from the database, for the page to update accordingly

  • We can approach it in two ways

  • In the first one, we just call getHolidays() again.

Let's try it, add this.getHolidays(); inside the response of the $http function inside this.createHoliday()

this.createHoliday = () => {
  $http({
    method: 'POST',
    url: '/holidays',
    data: this.createForm
  }).then(response => {
    this.getHolidays()
  }, error => {
    console.log(error)
  })
}

Don't forget to save your file and refresh your browser

The nice thing about doing it this way is that it is super easy, just one line of code. The downside is that it is another call to the database. For a small app that not many people use, it's not really a problem at all.

However, if you wanted to update the page without making a call to the database, you can do so by manipulating the holidays array.

Let's try it:

this.createHoliday = () => {
  $http({
    method: 'POST',
    url: '/holidays',
    data: this.createForm
  }).then(response => {
  // let's use unshift to put our latest holiday at the top of our list, rather than push which would add it to the bottom
    this.holidays.unshift(response.data)
  }, error => {
    console.log(error)
  })
}

You can add as much functionality as you like inside the .then() function. Another really nice to have feature, is to empty out the form after creating a new holiday.

We can do that by setting this.createForm to an empty object

We can also have our new holiday appear at the top of our list by using .unshift instead of push

this.createHoliday = () => {
  // console.log('submit button calls this function');
  $http({
    method: 'POST',
    url: '/holidays',
    data: this.createForm
  }).then(response => {
    this.holidays.unshift(response.data)
    this.createForm = {}
  }, error => {
    console.log(error)
  })
}

End of create lesson app appearance

Take aways

Even though Angular has some very specific rules and formatting, app.js is still Javascript and we can do as much or as little JavaScript as we like.

Onwards