1

I'm working with angular 1.5 and a python/mongodb api. The api is working fine (consistent and fast), but sometimes when I load a page with a form the data fields are empty.

The app uses ui.router to associate the chap state with the correct url and the chapController. I type that url into the address bar and hit return to load the page. In the controller, the path/to/api returns json data.

Here's a simplified version of the controller:

angular.module('configurer')
.controller('chapController', function($scope, $http, $state) {
    var url='path/to/api';
    $http.get(url).success(function(data){
        $scope.data = data;
    });

    $scope.save = function()( {
        $http.post(url, $scope.data).success(function() {
            $state.go('home', {reload:true});
        });
    });

The view looks like this:

<button class="btn btn-primary" ng-click="save()">Save Changes</button>
<form>
  <div class="row">
    <div class="col-sm-3 form-group">
      <label for="name">Name</label>
      <input class="form-control" id="name" type="text" name="name" ng-model="data.chap.name" />
    </div>
    <div class="col-sm-9 form-group">
      <label for="title">Title</label>
      <input class="form-control" id="title" type="text" title="title" ng-model="data.chap.title" />
    </div>
  </div>
</form>

Usually the form comes up populated with data but sometimes the fields are blank (using the same url). I can reload the page from the browser and then it will populate, but of course that's not a good user experience.

What am I doing wrong?

2
  • Try to initiate $scope.data with <ng-init> Commented Nov 30, 2016 at 16:48
  • I'm looking at the doc here and I don't see how to use it in my context: docs.angularjs.org/api/ng/directive/ngInit My data is a large json object. Commented Nov 30, 2016 at 18:58

3 Answers 3

1

After research plus trial-and-error, I think I've got the answer. The reason the scope wasn't binding to the data is that there was no data: my server was sending a 304 "not modified" response.

So of course it couldn't bind with non-existent data but the http response was still counted as success. Seems like this would be a common 'gotcha'.

What worked for me is to add a config object to each http.get call, like this

http.get(url, {cache:true}).success(function(data) { etc...

My guess is that you could also set max-age and public on the http request headers so the server cannot respond with a 304. That didn't seem like the most efficient thing to do, so I went with using cache on the client so the server isn't even bothered.

This is working for me, but if problems pop up again, I'll repost.

Sign up to request clarification or add additional context in comments.

Comments

0

Since you're using ui.router, I recommend using resolve for this.

Example:

$stateProvider
  .state('chap', {
    // ...
    resolve: {
      data: function($http){
        return $http.get(...);
      }
    }
  });

and in your controller:

angular
  .module('configurer')
  .controller('chapController', function(data, $scope, $http, $state) {
    $scope.data = data;
  }

2 Comments

I cannot get it to fail today, I'll return when I can reproduce. I'm reading about resolve now and it seems like it's for cases of nested states, but I don't have any of those.
resolve is useful for any state in which you want to ensure data is present before moving to that particular state. It's very relevant in cases where you might have a load overlay on your views, and want to block the entire view ou until data has been resolved.
0

Sometimes data won't bind with the scope. can you check by including this line

$scope.data = data;
$scope.$apply();

Inside success handler. I am not sure, it may work. please try

1 Comment

thanks, but the doc says that http calls finish with $scope.apply: jimhoskins.com/2012/12/17/angularjs-and-apply.html so I can't see how calling apply again would help.Still, as soon as I can reproduce the problem I'll see if it does help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.