Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -2,6 +2,6 @@
 import { Injectable } from '@angular/core';
 import { Action, Store } from '@ngrx/store';
-import { Observable, Subject, throwError } from 'rxjs';
-import { catchError, filter, map } from 'rxjs/operators';
+import { Observable, Subject } from 'rxjs';
+import { filter } from 'rxjs/operators';
 
 import {
@@ -9,5 +9,6 @@
   PreviewQuestionViewModel,
   QuestionStateViewModel,
-  SearchQuestionsQueryViewModel
+  SearchQuestionsQueryViewModel,
+  VoteType
 } from 'src/app/shared-app/models';
 import {
@@ -16,5 +17,6 @@
   GetPreviewQuestionsPopular,
   GetQuestionState,
-  GetSearchQuestions
+  GetSearchQuestions,
+  VoteAnswer
 } from './question-state/question.actions';
 import { questionStateQuery } from './question-state/question.selectors';
@@ -30,17 +32,5 @@
 
   constructor(private store: Store<QuestionState>) {
-    this.effectWorking$ = this.store.select(questionStateQuery.effectWorking).pipe(
-      filter((effect) => effect !== null),
-      map((effect) => {
-        if (effect instanceof HttpErrorResponse) {
-          throw effect;
-        } else {
-          return effect;
-        }
-      }),
-      catchError((err) => {
-        return throwError(err);
-      })
-    );
+    this.effectWorking$ = this.store.select(questionStateQuery.effectWorking).pipe(filter((effect) => effect !== null));
   }
 
@@ -81,4 +71,8 @@
   }
 
+  public voteAnswer(answerUid: string, questionUid: string, voteType: VoteType): void {
+    this.dispatchEffect(new VoteAnswer(questionUid, answerUid, voteType));
+  }
+
   public fetchQuestion(questionUid: string): void {
     this.dispatchEffect(new GetQuestionState(questionUid));
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-request.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-request.models.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-request.models.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -0,0 +1,5 @@
+import { VoteType } from 'src/app/shared-app/models';
+
+export class VoteAnswerRequest {
+  constructor(public voteType: VoteType) {}
+}
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-response.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-response.models.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-response.models.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -0,0 +1,82 @@
+import { VoteType } from 'src/app/shared-app/models';
+
+export class QuestionStateResponse {
+  public uid!: string;
+  public title!: string;
+  public text!: string;
+  public createdOn!: moment.Moment;
+  public views!: number;
+  public lastActiveOn!: moment.Moment;
+  public studentResponse!: StudentQuestionStateResponse;
+  public answersResponse!: AnswerQuestionStateResponse[];
+  public categoriesResponse!: QuestionCategoryQuestionStateResponse[];
+  public teamResponse!: TeamQuestionStateResponse | null;
+}
+
+export class StudentQuestionStateResponse {
+  public uid!: string;
+  public index!: string;
+  public imageUrl!: string;
+  public reputation!: number;
+}
+
+export class TeamQuestionStateResponse {
+  public uid!: string;
+  public name!: string;
+}
+
+export class QuestionCategoryQuestionStateResponse {
+  public uid!: string;
+  public name!: string;
+}
+
+export class AnswerQuestionStateResponse {
+  public uid!: string;
+  public text!: string;
+  public correctAnswer!: boolean;
+  public createdOn!: moment.Moment;
+  public votesCount!: number;
+  public studentResponse!: AnswerStudentQuestionStateResponse;
+  public answerResponsesResponse!: AnswerResponseQuestionStateResponse[];
+}
+
+export class AnswerStudentQuestionStateResponse {
+  public uid!: string;
+  public index!: string;
+  public imageUrl!: string;
+  public reputation!: number;
+}
+
+export class AnswerResponseQuestionStateResponse {
+  public uid!: string;
+  public text!: string;
+  public createdOn!: moment.Moment;
+  public studentResponse!: AnswerResponseStudentQuestionStateResponse;
+}
+
+export class AnswerResponseStudentQuestionStateResponse {
+  public uid!: string;
+  public index!: string;
+  public imageUrl!: string;
+  public reputation!: number;
+}
+
+export class PreviewQuestionResponse {
+  public uid!: string;
+  public title!: string;
+  public createdOn!: moment.Moment;
+  public views!: number;
+  public answersCount!: number;
+  public categories!: PreviewQuestionCategoryResponse[];
+}
+
+export class PreviewQuestionCategoryResponse {
+  public uid!: string;
+  public text!: string;
+}
+
+export class VoteAnswerResponse {
+  public answerUid!: string;
+  public voteUid!: string;
+  public voteType!: VoteType;
+}
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state.models.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ 	(revision )
@@ -1,74 +1,0 @@
-export class QuestionStateResponse {
-  public uid!: string;
-  public title!: string;
-  public text!: string;
-  public createdOn!: moment.Moment;
-  public views!: number;
-  public lastActiveOn!: moment.Moment;
-  public studentResponse!: StudentQuestionStateResponse;
-  public answersResponse!: AnswerQuestionStateResponse[];
-  public categoriesResponse!: QuestionCategoryQuestionStateResponse[];
-  public teamResponse!: TeamQuestionStateResponse | null;
-}
-
-export class StudentQuestionStateResponse {
-  public uid!: string;
-  public index!: string;
-  public imageUrl!: string;
-  public reputation!: number;
-}
-
-export class TeamQuestionStateResponse {
-  public uid!: string;
-  public name!: string;
-}
-
-export class QuestionCategoryQuestionStateResponse {
-  public uid!: string;
-  public name!: string;
-}
-
-export class AnswerQuestionStateResponse {
-  public uid!: string;
-  public text!: string;
-  public correctAnswer!: boolean;
-  public createdOn!: moment.Moment;
-  public votesCount!: number;
-  public studentResponse!: AnswerStudentQuestionStateResponse;
-  public answerResponsesResponse!: AnswerResponseQuestionStateResponse[];
-}
-
-export class AnswerStudentQuestionStateResponse {
-  public uid!: string;
-  public index!: string;
-  public imageUrl!: string;
-  public reputation!: number;
-}
-
-export class AnswerResponseQuestionStateResponse {
-  public uid!: string;
-  public text!: string;
-  public createdOn!: moment.Moment;
-  public studentResponse!: AnswerResponseStudentQuestionStateResponse;
-}
-
-export class AnswerResponseStudentQuestionStateResponse {
-  public uid!: string;
-  public index!: string;
-  public imageUrl!: string;
-  public reputation!: number;
-}
-
-export class PreviewQuestionResponse {
-  public uid!: string;
-  public title!: string;
-  public createdOn!: moment.Moment;
-  public views!: number;
-  public answersCount!: number;
-  public categories!: PreviewQuestionCategoryResponse[];
-}
-
-export class PreviewQuestionCategoryResponse {
-  public uid!: string;
-  public text!: string;
-}
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -2,5 +2,11 @@
 import { Action } from '@ngrx/store';
 
-import { PreviewQuestionViewModel, QuestionStateViewModel, SearchQuestionsQueryViewModel } from 'src/app/shared-app/models';
+import {
+  PreviewQuestionViewModel,
+  QuestionStateViewModel,
+  SearchQuestionsQueryViewModel,
+  VoteAnswerViewModel,
+  VoteType
+} from 'src/app/shared-app/models';
 
 export enum QuestionActionTypes {
@@ -13,4 +19,6 @@
   GetSearchQuestions = '[Question] Get search questions',
   GetSearchQuestionsSuccess = '[Question] Get search questions Success',
+  VoteAnswer = '[Question] Vote answer',
+  VoteAnswerSuccess = '[Question] Vote answer Success',
   EffectStartedWorking = '[Question] Effect Started Working',
   EffectFinishedWorking = '[Question] Effect Finished Working',
@@ -66,4 +74,16 @@
 }
 
+export class VoteAnswer implements Action {
+  readonly type = QuestionActionTypes.VoteAnswer;
+
+  constructor(public questionUid: string, public answerUid: string, public voteType: VoteType) {}
+}
+
+export class VoteAnswerSuccess implements Action {
+  readonly type = QuestionActionTypes.VoteAnswerSuccess;
+
+  constructor(public payload: VoteAnswerViewModel) {}
+}
+
 export class EffectStartedWorking implements Action {
   readonly type = QuestionActionTypes.EffectStartedWorking;
@@ -89,4 +109,5 @@
   | GetPreviewQuestionsPopularSuccess
   | GetSearchQuestionsSuccess
+  | VoteAnswerSuccess
   | EffectStartedWorking
   | EffectFinishedWorking
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -7,5 +7,6 @@
 import { BaseApiService } from 'src/app/shared-app/services/base-api.service';
 import { QuestionFacadeService } from '../question-facade.service';
-import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models';
+import { VoteAnswerRequest } from './question-state-request.models';
+import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models';
 import {
   EffectFinishedWorking,
@@ -19,5 +20,7 @@
   GetSearchQuestions,
   GetSearchQuestionsSuccess,
-  QuestionActionTypes
+  QuestionActionTypes,
+  VoteAnswer,
+  VoteAnswerSuccess
 } from './question.actions';
 import { QuestionMapper } from './question.mapper';
@@ -103,3 +106,16 @@
     );
   });
+
+  voteAnswer$ = createEffect(() => {
+    return this.actions$.pipe(
+      ofType<VoteAnswer>(QuestionActionTypes.VoteAnswer),
+      mergeMap((action) => {
+        const body = new VoteAnswerRequest(action.voteType);
+        return this.api.post<VoteAnswerResponse>(`v1/questions/${action.questionUid}/answers/${action.answerUid}/votes`, body).pipe(
+          switchMap((state) => [new VoteAnswerSuccess(QuestionMapper.ToVoteAnswerViewModel(state)), new EffectFinishedWorking()]),
+          catchError((err) => [new EffectFinishedWorkingError(err)])
+        );
+      })
+    );
+  });
 }
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -10,8 +10,9 @@
   QuestionStateViewModel,
   StudentQuestionStateViewModel,
-  TeamQuestionStateViewModel
+  TeamQuestionStateViewModel,
+  VoteAnswerViewModel
 } from 'src/app/shared-app/models';
 import { TranslateFromJsonService } from 'src/app/shared-app/services';
-import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models';
+import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models';
 
 export class QuestionMapper {
@@ -113,3 +114,7 @@
     return questions;
   }
+
+  public static ToVoteAnswerViewModel(response: VoteAnswerResponse): VoteAnswerViewModel {
+    return new VoteAnswerViewModel(response.answerUid, response.voteUid, response.voteType);
+  }
 }
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -1,2 +1,3 @@
+import { VoteType } from 'src/app/shared-app/models';
 import { QuestionAction, QuestionActionTypes } from './question.actions';
 import { initialState, QuestionState } from './question.state';
@@ -25,4 +26,39 @@
         searchQuestionsQuery: action.query
       };
+    case QuestionActionTypes.VoteAnswerSuccess: {
+      if (state.question) {
+        return {
+          ...state,
+          question: {
+            ...state.question,
+            answers: state.question.answers.map((x) => {
+              if (x.uid === action.payload.answerUid) {
+                let votesCountNew = x.votesCount;
+
+                switch (action.payload.voteType) {
+                  case VoteType.Upvote:
+                    votesCountNew++;
+                    break;
+                  case VoteType.Downvote:
+                    votesCountNew--;
+                    break;
+                }
+
+                return {
+                  ...x,
+                  votesCount: votesCountNew
+                };
+              }
+
+              return x;
+            })
+          }
+        };
+      }
+
+      return {
+        ...state
+      };
+    }
     case QuestionActionTypes.EffectStartedWorking: {
       return {
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -1,9 +1,5 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { VoteType } from 'src/app/shared-app/models';
 import { ButtonType } from '../button/button.models';
-
-export enum VoteType {
-  Upvote,
-  Downvote
-}
 
 @Component({
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -14,5 +14,10 @@
       <mat-card-content>
         <div fxLayout="row wrap" fxLayoutAlign="space-around none">
-          <app-vote [voteCount]="answer.votesCount" [correct]="answer.correctAnswer" fxFlex="6%"></app-vote>
+          <app-vote
+            [voteCount]="answer.votesCount"
+            [correct]="answer.correctAnswer"
+            (voteClicked)="answerVoted($event, answer.uid, question.uid)"
+            fxFlex="6%"
+          ></app-vote>
           <div fxFlex="92%">
             <app-text-editor
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -1,6 +1,8 @@
+import { HttpErrorResponse } from '@angular/common/http';
 import { Component, OnInit } from '@angular/core';
+import { NotificationService } from 'src/app/core/services/notification.service';
 import { QuestionFacadeService } from 'src/app/core/state/question-facade.service';
 
-import { QuestionStateViewModel } from 'src/app/shared-app/models';
+import { QuestionStateViewModel, VoteType } from 'src/app/shared-app/models';
 import { ButtonType } from '../../generic/button/button.models';
 
@@ -14,5 +16,5 @@
   working = true;
   ButtonType = ButtonType;
-  constructor(private questionFacade: QuestionFacadeService) {}
+  constructor(private questionFacade: QuestionFacadeService, private notification: NotificationService) {}
 
   ngOnInit(): void {
@@ -21,4 +23,14 @@
       this.working = false;
     });
+
+    this.questionFacade.effectWorking$.subscribe((effect) => {
+      if (effect instanceof HttpErrorResponse) {
+        this.notification.handleErrorsNotification(effect.error);
+      }
+    });
+  }
+
+  answerVoted(voteType: VoteType, answerUid: string, questionUid: string): void {
+    this.questionFacade.voteAnswer(answerUid, questionUid, voteType);
   }
 }
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-enums.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-enums.models.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-enums.models.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -3,2 +3,7 @@
   Popular
 }
+
+export enum VoteType {
+  Upvote,
+  Downvote
+}
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -1,2 +1,4 @@
+import { VoteType } from '.';
+
 export class QuestionStateViewModel {
   constructor(
@@ -73,2 +75,6 @@
   constructor(public text: string) {}
 }
+
+export class VoteAnswerViewModel {
+  constructor(public answerUid: string, public voteUid: string, public voteType: VoteType) {}
+}
Index: src/Clients/Angular/finki-chattery/src/assets/translations/en.json
===================================================================
--- src/Clients/Angular/finki-chattery/src/assets/translations/en.json	(revision ad0fcd30ce5ab16c07db1be60f8ef94fd38446b8)
+++ src/Clients/Angular/finki-chattery/src/assets/translations/en.json	(revision 80e2fe00b56a1e7950b3722c072b0ef652694640)
@@ -53,4 +53,7 @@
   "ask-question-stepper-ask": "Ask question",
   "ask-question-ask-button-back": "Edit question",
-  "ask-question-ask-button": "Ask question"
+  "ask-question-ask-button": "Ask question",
+  "AnswerAlreadyUpvoted": "You have already upvoted this answer",
+  "AnswerAlreadyDownvoted": "You have already downvoted this answer",
+  "StudentHasBadReputation": "You have bad reputation and can not vote"
 }
