2

With Node.js active in my terminal, I have noticed when I click on a link to any route in my Angular application, there is no GET request to that route. However, when I reload, the GET request suddenly appears. I have heard of the "2 requests per resource" behaviour, but don't quite understand it.

Any $http.get method is displayed however, even upon first request. This causes me headaches, as I'm trying to display a dynamic list of entries loaded through the database. They only appear on the second request.

First "click" (logs from node on the server)

GET /api/entries 200 4ms - 157b
adding the entries on the server side

the /api/entries get request originates from $http.get in code

Second "click" - the same route (achieved by reloading the page)

GET /api/entries 200 3ms - 157b
adding the entries on the server side
GET /list 200 23ms - 713b
GET /css/app.css 304 1ms
GET /css/bootstrap/bootstrap.min.css 304 4ms
GET /js/lib/angular/angular-ui.min.js 304 7ms
GET /js/app.js 304 9ms
GET /js/services.js 304 12ms
GET /js/lib/angular/angular.js 304 7ms
GET /js/controllers.js 304 5ms
GET /js/filters.js 304 6ms
GET /js/directives.js 304 11ms
GET /partials/directives/navitem 200 4ms - 144b
GET /partials/directives/navigation 200 6ms - 88b
GET /partials/list 200 9ms - 77b
GET /favicon.ico 200 19ms - 713b

As you can see, there now is a /list GET request.

How could I fix this?

This is my List Controller:

... preceding controllers ...

.controller('ListController', ['$scope', '$http', function($scope, $http) {
    console.log('The controller has been executed');
    $http.get('api/entries')
    .success(function(data) {
        $scope.entries = data.entries;
    });
}])

This controller is bound to the /list route

How could I make it so, that the entries dragged from the database are displayed upon the first request?

I found some information about this issue here: Does Angularjs really require two requests per resource?, however, I can't find the solution yet.

This the Jade, that compiles to HTML for, the list route

ul
    li.well(ng-repeat='entry in entries')  {{ entry.text }}

The index page

extends layout

block body

    section#container
        panel
            logo(redirect='write')  Diary 
            navigation
                item(redirect='write')  Write 
                item(redirect='list')  List 

        div(ng-view)

    script(src='js/lib/angular/angular.js')
    script(src = 'js/lib/angular/angular-ui.min.js')
    script(src='js/app.js')
    script(src='js/services.js')
    script(src='js/controllers.js')
    script(src='js/filters.js')
    script(src='js/directives.js')
Community
  • 1
  • 1
Rasteril
  • 605
  • 1
  • 5
  • 16

1 Answers1

0

I don't fully understand your question, so please let me know if I misunderstood.

There are two different routing types that you seem to imply are one. The client routing, which is the part after the #, is done client-side only, and the server routing, in these applications usually for JSON/XML data.

After the HTML/JS/CSS is loaded initially (from the master page), AngularJS does client routing. So navigating from #/products to #/products/5 is a client-side-only change. AngularJS will then retrieve from cache or request from the server the template (if specified) and run the controller code, it will place that template into the tag with ngView. It will not do a server request to #/products/5 nor will it redownload (or even re-evaluate) the master page, CSS, JS, et cetera. Unless you press F5, in which case the browser will throw it all away and start anew. AngularJS has no control over that.

In your scenario, I believe, the master page contains a layout and some CSS/JS references. These are all parsed by the browser and AngularJS is bootstrapped. The controller code runs, and does the API request. When you click towards another client route, AngularJS executes that controller's code which does another request, and replaces ngView. When you F5 (your second scenario), this whole process is restarted.

HTH

Steve Klösters
  • 9,427
  • 2
  • 42
  • 53
  • In my controller code, you can see me assigning the results of the GET request from the server to the local scope variable, but the scope does not refresh after that happens. I have to go to another route, and back again to see the results. There are many things unclear to me at this point. – Rasteril Aug 07 '13 at 09:37
  • Perhaps you're experiencing a binding issue. Could you add the relevant HTML to your question? – Steve Klösters Aug 07 '13 at 09:40
  • I have added the relevant HTML, it's in Jade format however. Hope it's not going to be much of a problem. – Rasteril Aug 07 '13 at 09:54
  • HTML looks fine. Are you aware that you are looking at two different values in your JS? `$scope.entries = data.data.entries;` vs. `console.log(data.entries);` – Steve Klösters Aug 07 '13 at 10:03
  • Oh, I was just messing around with promises, because before it as just a standard .success(callback). I am aware of that (forgot to clear it out for SO (fixed it now) ). I think the problem might be in what you said in your answer. Does the page have to reload for angular's http.get() to be processed? I click on the link and it works only when I reload the page. – Rasteril Aug 07 '13 at 10:45
  • I guess I have to program a mechanism, that would automatically check for changes in the database? A button works just fine, but I would like it to download automatically... – Rasteril Aug 07 '13 at 11:05