Correct way to create a Facebook-like feed


#1

Hello!

I’m having trouble creating a simple feed, similar to that of Facebook. I mainly need advice on the general way of doing it - for example, should I load the data from the site’s server using a http request and store the generated json data in an array within a service? Where should the http code be - in the service or in the controller? How would I get the data to appear as soon as it’s loaded (at the moment the data only appears once I change page and go back)?

At the moment this is my service:

.service('PostService', function($http, localStorageService) {

var posts;

$http.get('http://localhost/backend/feed.php', {
	params: {
		id: localStorageService.get('id'),
		token: localStorageService.get('token')
	}
}).
success(function(data, status, headers, config) {
	posts = data;
}).
error(function(data, status, headers, config) {
	alert("Can't connect to the database.");
});

this.get = function() {
	return posts;
}
})

And this is my controller:

.controller('PostIndexCtrl', function($scope) {

$scope.posts = PostService.get();

})

I’m pretty confused about the best way to do this and I would appreciate any help in the matter. Is it possible for someone to type out a very simple example of a functioning feed?

Thanks very much!


#2

Your $http call belongs in your service, as you have shown here.

However, you should probably make use of the promise returned by the $http service. Otherwise, your $scope.posts will always be initially bound to an undefined value. Since you expect it to eventually return a collection, you would at least want to return an empty array at the time of loading. But you would probably be better served by firing off the request at the time of assignment to $scope.posts.

.service('PostService', function($http, localStorageService) {
        
  var posts = function(){
    return $http.get('http://localhost/backend/feed.php', {
        params: {
        id: localStorageService.get('id'),
        token: localStorageService.get('token')
      }
    }).
    success(function(data, status, headers, config) {
      return data;
    }).
    error(function(data, status, headers, config) {
      alert("Can't connect to the database.");
      return [];
    });
  };

  this.get = function() {
    return posts();
  };
});

#3

Thanks very much for your help, Adrichman.
I’ve changed my service to how you advised, but now it comes up with more posts than expected, and none of the values in the array are there. For example, if I write:

success(function(data, status, headers, config) {
  alert(data);
  return data;
}).

I get an alert with:
[object Object],[object Object],[object Object]

When I have:

success(function(data, status, headers, config) {
  alert(data[0]['id']);
  return data;
}).

I get the id of one of the posts. Not sure exactly why it’s not working as expected - maybe you know? Many thanks again!


#4

Is there anybody that’s able to help with this problem? I can’t figure it out! Many thanks in advance if you’re able to.


#5

Hi ady sorry to have only just seen this now.
It sounds like you are returning the data that you want. Could you clarify what is unexpected about this behavior? If you console.log those objects you can inspect them further. Alert can only show you strings.


#6

Hi Adrichman,
No problem at all! I appreciate all help I can get.
The unexpected part of this is where the data doesn’t show up in the app. There are 3 posts that are returned from the server, but in the app there are 5 blank posts. When I output the data variable, it comes up with:

[Object, Object, Object]

When I expand this, I get:

> 0: Object
> 1: Object
> 2: Object
length: 3
> __proto__: Array[0]

And inside each of the 3 objects there is the post information. This is in my controller:

$scope.posts = PostService.get();

And this is the template:

<div ng-repeat="post in posts">
    {{post.id}}
</div>

#7

do you have the full code somewhere?


#8

Hi Adrichman,
I’ve simplified my app and uploaded it here: http://www.speedyshare.com/4kPRf/app.zip

Thanks a lot for taking a look at it.


#9

hi ady, because PostService.get returns a promise when invoked (because we are returning the promise $http call), you just need to delay the assignment of the value of $scope.posts until the promise resolves.

	PostService.get().then(function(data){ 
	  $scope.posts = data.data; 
        });

#10

That works perfectly. Thanks very much for your help with all this - you fixed a problem I’ve been trying to figure out for 2 weeks!