SmileTable – Home Page Posts: backend

Displaying posts on SmileTable board works not so bad, and in this post I want to introduce It.Home Page is heart of SmileTable application. I realize that after spend some hours working on It. I seen how many attention and focus was needed from me to create what I wanted to create. In this post I just want to focus on Index action method in HomeController which is responsible for displaying posts.

Every single post contains header with info like author name, main body with photo or movie and of course description. Every single post may have many comments and add new comment option is needed. If we are logged we want to know which post are liked by us. Of course there is more like delete post, share post etc, but for now let’s focus just on display posts.

In Index action method I need to create viewmodel which ensure me access to all data which I have mentioned. It is neccessery to create Wrapper View model with many models.
I named my view model just like action method. I know maybe It’s no good practice because we may have more Index action methods, but I let it go for now.

In my IndexViewModel I keep two properties which are return objects. I assign instance to that properties in Index action method.

public class IndexViewModel
{
    public CreateNewPostModel CreateNewPost { get; set; }
    public IEnumerable<DisplayPostsModel> DisplayPosts { get; set; }
}

For start let’s think deeper about Index action method. What is important we don’t want to display all posts on the first time. If we will try to get for example 10000 posts from database and display them on the page I am sure that It will be block entire application and maybe throw an exception.

There is neccessery to get specified count of posts. I will talk about that in next posts so for now I just want to say that I am using something like Infinite Scrolling.
I am mentioning about It now because Index action method in header have two nullable parameters: int? displayPostCount and int? skipPostCoutIndex. If Index action method is invoked from jQuery code I send value to these arguments.
If Index action method is invoked I specify how many post I want do download from database to append them to already displaying. For start page skipPostCountIndex is equal to 0. skipPostCountIndex is increment on clientSide in jQuery after we want to display next posts.

I am using nullable types because like I sed displayPostCount and skipPostCoutIndex have only value when Index action method is invoked from jQuery.

To know if Index arguments have value I am using ?? operator.

public HomeController(IPostRepository postRepository, IUserRepository userRepository
, IRatePostRepository ratePostRepository, ICommentRepository commentRepository)
{
    _postRepository = postRepository;
    _userRepository = userRepository;
    _ratePostRepository = ratePostRepository;
    _commentRepository = commentRepository;
}

public ActionResult Index(int? displayPostCount, int? skipPostCountIndex)
{
    List<int> userLikedPostsId;

    int _displayPostCount = displayPostCount ?? 6;
    int _skipPostCountIndex = skipPostCountIndex ?? 0;

I know how many post I want to download from database and I know how many I want to skip.To get post I am using repository pattern connected with dependency injection so that is why I am not creating new instance of my repository. Dependency Injection container do It for me and send me that instance to my HomeController constructor.

List<Post> posts = _postRepository.GetPostsToDisplay(_skipPostCountIndex, 
_displayPostCount);

Next I am creating DisplayPostModel and fill inside properties with data from database.
There is one property worth attention. Buttons like delete post or report post are important and I need to know which post I can delete. For that I am using IsCurrentlyLoggedUserPost property

List<DisplayPostsModel> displayPosts;

displayPosts = posts.Select(p => new DisplayPostsModel
{
    PostId = p.PostId,
    Message = p.Message,
    IsCurrentlyLoggedUserPost = User.Identity.GetUserId() == p.ApplicationUser.Id
    ? true : false,
    PostImageData = p.PostImageData,
    UserImageData = p.ApplicationUser.UserImageData,
    UserFullName = p.ApplicationUser.FirstName + " " + p.ApplicationUser.LastName
}).ToList();

Of course there is no finished model because I will need for sure more data.

Next very important thing is to mark posts which are liked by user. To do that I need to have data about It in my view. For that responsible is code:

if (User.Identity.IsAuthenticated)
{
    userLikedPostsId = _userRepository.GetSingleUserById(User.Identity.GetUserId())
    .RatePosts.Select(p => p.PostId).ToList();

    if (userLikedPostsId.Count > 0)
        displayPosts.Where(p => userLikedPostsId.Contains(p.PostId)).ToList()
        .ForEach(p => p.isLiked = true);
}

Let’s explain what I am doing.
To don’t throw an exception I check If user is signed. Next I get from database list of posts id which was rated by curently logged user. If list of ids is not empty I check if any post I want to display have Id simmilar to Id from list. If have I set isLiked property to true. Now I know which post are liked and I can give them suitable style property.

Last if else condition is connected with Index action method arguments. Like I mentioned If Index method is invoked from jQuery I want to append next post to already displayed on page. I don’t need and I don’t want to return whole view again that is why I am using Ajax and return partial view. I don’t want to introduce details about that now, I want to say If I call Index from ajax jQuery to append next post I just return partial view because I don’t need to return more, and If I run Index after redirect or start I return entire model with view.

if (Request.IsAjaxRequest())
        return PartialView("_DisplayPosts", displayPosts);
else
{
    var viewModel = new IndexViewModel()
    {
        DisplayPosts = displayPosts.AsEnumerable()
    };

    return View(viewModel);
}

That all what I described allow me to display posts, check if are rated or no, and append next post after scroll on bottom page. I am happy about my Index action method and I think It’s no so bad 🙂

Reklamy

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Zdjęcie na Google+

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s