Index: src/Clients/Angular/finki-chattery/src/app/core/services/student-question.service.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/services/student-question.service.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/Clients/Angular/finki-chattery/src/app/core/services/student-question.service.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,18 @@
+import { Injectable } from '@angular/core';
+import { AnswerQuestionStateViewModel, AnswerResponseQuestionStateViewModel } from 'src/app/shared-app/models';
+import { AuthService } from '.';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class StudentQuestionService {
+  constructor(private auth: AuthService) {}
+
+  currentUserCanEditAnswer(answer: AnswerQuestionStateViewModel): boolean {
+    return this.auth.selfUser?.student?.uid === answer.student.uid;
+  }
+
+  currentUserCanEditAnswerResponse(answerResponse: AnswerResponseQuestionStateViewModel): boolean {
+    return this.auth.selfUser?.student?.uid === answerResponse.student.uid;
+  }
+}
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 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -15,4 +15,6 @@
 import {
   AnswerQuestion,
+  EditAnswerQuestion,
+  EditAnswerResponse,
   EffectStartedWorking,
   GetPreviewQuestionsLatest,
@@ -91,4 +93,12 @@
   }
 
+  public editAnswerResponse(answerUid: string, questionUid: string, answerResponseUid: string, text: string): void {
+    this.dispatchEffect(new EditAnswerResponse(questionUid, answerUid, answerResponseUid, text));
+  }
+
+  public editAnswer(answerUid: string, questionUid: string, text: string): void {
+    this.dispatchEffect(new EditAnswerQuestion(questionUid, answerUid, text));
+  }
+
   public fetchQuestion(questionUid: string): void {
     this.dispatchEffect(new GetQuestionState(questionUid));
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 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -29,7 +29,35 @@
   AnswerQuestion = '[Question] AnswerQuestion',
   AnswerQuestionSuccess = '[Question] AnswerQuestion Success',
+  EditAnswerQuestion = '[Question] EditAnswerQuestion',
+  EditAnswerQuestionSuccess = '[Question] EditAnswerQuestion Success',
+  EditAnswerResponse = '[Question] EditAnswerResponse',
+  EditAnswerResponseSuccess = '[Question] EditAnswerResponse Success',
   EffectStartedWorking = '[Question] Effect Started Working',
   EffectFinishedWorking = '[Question] Effect Finished Working',
   EffectFinishedWorkingError = '[Question] Effect Finished Working error'
+}
+
+export class EditAnswerQuestion implements Action {
+  readonly type = QuestionActionTypes.EditAnswerQuestion;
+
+  constructor(public questionUid: string, public answerUid: string, public text: string) {}
+}
+
+export class EditAnswerQuestionSuccess implements Action {
+  readonly type = QuestionActionTypes.EditAnswerQuestionSuccess;
+
+  constructor(public payload: AnswerQuestionStateViewModel, public answerUid: string) {}
+}
+
+export class EditAnswerResponse implements Action {
+  readonly type = QuestionActionTypes.EditAnswerResponse;
+
+  constructor(public questionUid: string, public answerUid: string, public answerResponseUid: string, public text: string) {}
+}
+
+export class EditAnswerResponseSuccess implements Action {
+  readonly type = QuestionActionTypes.EditAnswerResponseSuccess;
+
+  constructor(public payload: AnswerResponseQuestionStateViewModel, public answerUid: string, public answerResponseUid: string) {}
 }
 
@@ -157,4 +185,6 @@
   | RespondToAnswerSuccess
   | AnswerQuestionSuccess
+  | EditAnswerQuestionSuccess
+  | EditAnswerResponseSuccess
   | 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 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -19,4 +19,8 @@
   AnswerQuestion,
   AnswerQuestionSuccess,
+  EditAnswerQuestion,
+  EditAnswerQuestionSuccess,
+  EditAnswerResponse,
+  EditAnswerResponseSuccess,
   EffectFinishedWorking,
   EffectFinishedWorkingError,
@@ -186,3 +190,49 @@
     );
   });
+
+  editResponseToAnswer$ = createEffect(() => {
+    return this.actions$.pipe(
+      ofType<EditAnswerResponse>(QuestionActionTypes.EditAnswerResponse),
+      mergeMap((action) => {
+        return this.api
+          .put<AnswerResponseQuestionStateResponse>(
+            `v1/questions/${action.questionUid}/answers/${action.answerUid}/answerresponses/${action.answerResponseUid}`,
+            new RespondToAnswerRequest(action.text)
+          )
+          .pipe(
+            tap((state) => this.notification.successNotification('success-edit-answer-response')),
+            switchMap((state) => [
+              new EditAnswerResponseSuccess(
+                QuestionMapper.ToAnswerResponseQuestionStateViewModel(state),
+                action.answerUid,
+                action.answerResponseUid
+              ),
+              new EffectFinishedWorking()
+            ]),
+            catchError((err) => [new EffectFinishedWorkingError(err)])
+          );
+      })
+    );
+  });
+
+  editAnswer$ = createEffect(() => {
+    return this.actions$.pipe(
+      ofType<EditAnswerQuestion>(QuestionActionTypes.EditAnswerQuestion),
+      mergeMap((action) => {
+        return this.api
+          .put<AnswerQuestionStateResponse>(
+            `v1/questions/${action.questionUid}/answers/${action.answerUid}`,
+            new AnswerQuestionRequest(action.text)
+          )
+          .pipe(
+            tap((state) => this.notification.successNotification('success-edit-answer')),
+            switchMap((state) => [
+              new EditAnswerQuestionSuccess(QuestionMapper.ToAnswerQuestionStateViewModel(state), action.answerUid),
+              new EffectFinishedWorking()
+            ]),
+            catchError((err) => [new EffectFinishedWorkingError(err)])
+          );
+      })
+    );
+  });
 }
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 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -114,4 +114,52 @@
       };
     }
+    case QuestionActionTypes.EditAnswerResponseSuccess: {
+      if (state.question) {
+        return {
+          ...state,
+          question: {
+            ...state.question,
+            answers: state.question.answers.map((x) => {
+              if (x.uid === action.answerUid) {
+                return {
+                  ...x,
+                  answerResponses: [...x.answerResponses.filter((y) => y.uid !== action.answerResponseUid), action.payload]
+                };
+              }
+
+              return x;
+            })
+          }
+        };
+      }
+
+      return {
+        ...state
+      };
+    }
+    case QuestionActionTypes.EditAnswerQuestionSuccess: {
+      if (state.question) {
+        return {
+          ...state,
+          question: {
+            ...state.question,
+            answers: state.question.answers.map((x) => {
+              if (x.uid === action.answerUid) {
+                return {
+                  ...x,
+                  text: action.payload.text
+                };
+              }
+
+              return x;
+            })
+          }
+        };
+      }
+
+      return {
+        ...state
+      };
+    }
     case QuestionActionTypes.AnswerQuestionSuccess: {
       if (state.question) {
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/components.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/components.ts	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/components.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -7,4 +7,6 @@
 import { AnswerQuestionComponent } from './question/answer-question/answer-question.component';
 import { AskQuestionSharedComponent } from './question/ask-question-shared/ask-question-shared.component';
+import { EditAnswerDialogComponent } from './question/edit-answer-dialog/edit-answer-dialog.component';
+import { EditAnswerResponseDialogComponent } from './question/edit-answer-response-dialog/edit-answer-response-dialog.component';
 import { PreviewQuestionDisplayComponent } from './question/preview-question-display/preview-question-display.component';
 import { PreviewQuestionFullComponent } from './question/preview-question-full/preview-question-full.component';
@@ -28,4 +30,6 @@
   TextEditorComponent,
   RespondToAnswerDialogComponent,
-  AnswerQuestionComponent
+  AnswerQuestionComponent,
+  EditAnswerDialogComponent,
+  EditAnswerResponseDialogComponent
 ];
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.html
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.html	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.html	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,14 @@
+<h1 mat-dialog-title>{{ 'edit-answer-title' | translate }}</h1>
+<mat-dialog-content>
+  <form [formGroup]="formGroup">
+    <app-text-editor [textForm]="textField" [text]="this.textFieldValue"></app-text-editor>
+  </form>
+</mat-dialog-content>
+<mat-dialog-actions>
+  <app-button class="margin-right-sm" [buttonType]="ButtonType.Basic" (action)="dialogRef.close()">
+    {{ 'close-button' | translate }}
+  </app-button>
+  <app-button [buttonType]="ButtonType.CallToAction" [disabled]="!formGroup.valid" (action)="submit()">
+    {{ 'submit-button' | translate }}
+  </app-button>
+</mat-dialog-actions>
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.spec.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.spec.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.spec.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditAnswerDialogComponent } from './edit-answer-dialog.component';
+
+describe('EditAnswerDialogComponent', () => {
+  let component: EditAnswerDialogComponent;
+  let fixture: ComponentFixture<EditAnswerDialogComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ EditAnswerDialogComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(EditAnswerDialogComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-dialog/edit-answer-dialog.component.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,36 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, Validators, FormGroup } from '@angular/forms';
+import { MatDialogRef } from '@angular/material/dialog';
+
+import { QuestionFacadeService } from 'src/app/core/state/question-facade.service';
+import { ButtonType } from '../../generic/button/button.models';
+
+@Component({
+  selector: 'app-edit-answer-dialog',
+  templateUrl: './edit-answer-dialog.component.html',
+  styleUrls: ['./edit-answer-dialog.component.scss']
+})
+export class EditAnswerDialogComponent implements OnInit {
+  public ButtonType = ButtonType;
+  public textField = new FormControl('', [Validators.required, Validators.maxLength(4000)]);
+  public formGroup: FormGroup;
+  public questionUid!: string;
+  public answerUid!: string;
+  public answerResponseUid!: string;
+  public textFieldValue!: string;
+
+  constructor(public dialogRef: MatDialogRef<EditAnswerDialogComponent>, private questionFacade: QuestionFacadeService) {
+    this.formGroup = new FormGroup({
+      text: this.textField
+    });
+  }
+
+  ngOnInit(): void {
+    this.textField.setValue(this.textFieldValue);
+  }
+
+  submit(): void {
+    this.questionFacade.editAnswer(this.answerUid, this.questionUid, this.textField.value);
+    this.dialogRef.close();
+  }
+}
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.html
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.html	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.html	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,21 @@
+<h1 mat-dialog-title>{{ 'edit-respond-to-answer-title' | translate }}</h1>
+<mat-dialog-content>
+  <form [formGroup]="formGroup">
+    <mat-form-field class="full-width margin-bottom-md" appearance="standard" appHandleInputFormErrors>
+      <textarea
+        matInput
+        autocomplete="off"
+        [placeholder]="'respond-to-answer-title-text-placeholder' | translate"
+        [formControl]="textField"
+      ></textarea>
+    </mat-form-field>
+  </form>
+</mat-dialog-content>
+<mat-dialog-actions>
+  <app-button class="margin-right-sm" [buttonType]="ButtonType.Basic" (action)="dialogRef.close()">
+    {{ 'close-button' | translate }}
+  </app-button>
+  <app-button [buttonType]="ButtonType.CallToAction" [disabled]="!formGroup.valid" (action)="submit()">
+    {{ 'submit-button' | translate }}
+  </app-button>
+</mat-dialog-actions>
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.spec.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.spec.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.spec.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditAnswerResponseDialogComponent } from './edit-answer-response-dialog.component';
+
+describe('EditAnswerResponseDialogComponent', () => {
+  let component: EditAnswerResponseDialogComponent;
+  let fixture: ComponentFixture<EditAnswerResponseDialogComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ EditAnswerResponseDialogComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(EditAnswerResponseDialogComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/edit-answer-response-dialog/edit-answer-response-dialog.component.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,36 @@
+import { Component, OnInit } from '@angular/core';
+import { FormControl, Validators, FormGroup } from '@angular/forms';
+import { MatDialogRef } from '@angular/material/dialog';
+
+import { QuestionFacadeService } from 'src/app/core/state/question-facade.service';
+import { ButtonType } from '../../generic/button/button.models';
+
+@Component({
+  selector: 'app-edit-answer-response-dialog',
+  templateUrl: './edit-answer-response-dialog.component.html',
+  styleUrls: ['./edit-answer-response-dialog.component.scss']
+})
+export class EditAnswerResponseDialogComponent implements OnInit {
+  public ButtonType = ButtonType;
+  public textField = new FormControl('', [Validators.required, Validators.maxLength(4000)]);
+  public formGroup: FormGroup;
+  public questionUid!: string;
+  public answerUid!: string;
+  public answerResponseUid!: string;
+  public textFieldValue!: string;
+
+  constructor(public dialogRef: MatDialogRef<EditAnswerResponseDialogComponent>, private questionFacade: QuestionFacadeService) {
+    this.formGroup = new FormGroup({
+      text: this.textField
+    });
+  }
+
+  ngOnInit(): void {
+    this.textField.setValue(this.textFieldValue);
+  }
+
+  submit(): void {
+    this.questionFacade.editAnswerResponse(this.answerUid, this.questionUid, this.answerResponseUid, this.textField.value);
+    this.dialogRef.close();
+  }
+}
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 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -47,4 +47,10 @@
               <mat-chip class="cursor">{{ answerResponse.student.index }}</mat-chip> -
               {{ answerResponse.createdOn | momentDate: 'LL' }}
+              <span
+                class="cursor text-bold"
+                *ngIf="studentQuestion.currentUserCanEditAnswerResponse(answerResponse)"
+                (click)="editAnswerResponse(question.uid, answer.uid, answerResponse.uid, answerResponse.text)"
+                >{{ 'question-preview-edit-answer-response' | translate }}</span
+              >
               <hr />
             </div>
@@ -56,4 +62,10 @@
           'question-preview-respond-to-answer-button' | translate
         }}</app-button>
+        <app-button
+          *ngIf="studentQuestion.currentUserCanEditAnswer(answer)"
+          (action)="editAnswer(question.uid, answer.uid, answer.text)"
+          [buttonType]="ButtonType.Basic"
+          >{{ 'question-preview-edit-answer' | translate }}</app-button
+        >
       </mat-card-actions>
     </mat-card>
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 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -2,4 +2,5 @@
 import { Component, OnInit } from '@angular/core';
 import { NotificationService } from 'src/app/core/services/notification.service';
+import { StudentQuestionService } from 'src/app/core/services/student-question.service';
 import { QuestionFacadeService } from 'src/app/core/state/question-facade.service';
 
@@ -21,5 +22,6 @@
     private questionFacade: QuestionFacadeService,
     private notification: NotificationService,
-    private dialog: SharedDialogService
+    private dialog: SharedDialogService,
+    public studentQuestion: StudentQuestionService
   ) {}
 
@@ -48,3 +50,11 @@
     this.dialog.respondToAnswer(this.question.uid, answerUid);
   }
+
+  editAnswer(questionUid: string, answerUid: string, text: string): void {
+    this.dialog.editAnswer(questionUid, answerUid, text);
+  }
+
+  editAnswerResponse(questionUid: string, answerUid: string, answerResponseUid: string, text: string): void {
+    this.dialog.editResponseToAnswer(questionUid, answerUid, answerResponseUid, text);
+  }
 }
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/respond-to-answer-dialog/respond-to-answer-dialog.component.html
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/respond-to-answer-dialog/respond-to-answer-dialog.component.html	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/respond-to-answer-dialog/respond-to-answer-dialog.component.html	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -13,5 +13,5 @@
 </mat-dialog-content>
 <mat-dialog-actions>
-  <app-button [buttonType]="ButtonType.Basic" (action)="dialogRef.close()">
+  <app-button class="margin-right-sm" [buttonType]="ButtonType.Basic" (action)="dialogRef.close()">
     {{ 'close-button' | translate }}
   </app-button>
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/services/shared-dialog.service.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/services/shared-dialog.service.ts	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/services/shared-dialog.service.ts	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -2,4 +2,7 @@
 import { MatDialog, MatDialogRef } from '@angular/material/dialog';
 import { Observable } from 'rxjs';
+import { EditAnswerDialogComponent } from '../components/question/edit-answer-dialog/edit-answer-dialog.component';
+// tslint:disable-next-line: max-line-length
+import { EditAnswerResponseDialogComponent } from '../components/question/edit-answer-response-dialog/edit-answer-response-dialog.component';
 import { RespondToAnswerDialogComponent } from '../components/question/respond-to-answer-dialog/respond-to-answer-dialog.component';
 
@@ -22,3 +25,32 @@
     return dialogRef.afterClosed();
   }
+
+  public editResponseToAnswer(questionUid: string, answerUid: string, answerResponseUid: string, text: string): Observable<any> {
+    let dialogRef: MatDialogRef<EditAnswerResponseDialogComponent>;
+    dialogRef = this.dialog.open(EditAnswerResponseDialogComponent, {
+      width: '650px',
+      height: 'auto'
+    });
+
+    dialogRef.componentInstance.questionUid = questionUid;
+    dialogRef.componentInstance.answerUid = answerUid;
+    dialogRef.componentInstance.answerResponseUid = answerResponseUid;
+    dialogRef.componentInstance.textFieldValue = text;
+
+    return dialogRef.afterClosed();
+  }
+
+  public editAnswer(questionUid: string, answerUid: string, text: string): Observable<any> {
+    let dialogRef: MatDialogRef<EditAnswerDialogComponent>;
+    dialogRef = this.dialog.open(EditAnswerDialogComponent, {
+      width: '650px',
+      height: 'auto'
+    });
+
+    dialogRef.componentInstance.questionUid = questionUid;
+    dialogRef.componentInstance.answerUid = answerUid;
+    dialogRef.componentInstance.textFieldValue = text;
+
+    return dialogRef.afterClosed();
+  }
 }
Index: src/Clients/Angular/finki-chattery/src/assets/translations/en.json
===================================================================
--- src/Clients/Angular/finki-chattery/src/assets/translations/en.json	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/Clients/Angular/finki-chattery/src/assets/translations/en.json	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -67,4 +67,10 @@
   "answer-question-title": "Give your answer to the question",
   "answer-question-button": "Answer",
+  "success-edit-answer-response": "Successfully edited response to answer",
+  "success-edit-answer": "Successfully edited answer",
+  "edit-respond-to-answer-title": "Edit answer response",
+  "edit-answer-title": "Edit answer",
+  "question-preview-edit-answer": "Edit answer",
+  "question-preview-edit-answer-response": "Edit response",
   "StudentDoesNotOwnQuestion": "You do not own this question",
   "AnswerAlreadyUpvoted": "You have already upvoted this answer",
Index: src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswerResponsesController.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswerResponsesController.cs	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswerResponsesController.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -31,4 +31,12 @@
             return Ok(answerResponse.ToAnswerResponseQuestionStateResponse());
         }
+
+        [HttpPut("{answerResponseUid:Guid}")]
+        [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthenticationPolicy.Student)]
+        public async Task<IActionResult> EditAnswerResponse([FromRoute] Guid questionUid, [FromRoute] Guid answerUid, [FromRoute] Guid answerResponseUid, [FromBody] AnswerResponseRequest request)
+        {
+            var answerResponse = await MediatorService.SendAsync(new EditAnswerResponseCommand(questionUid, answerUid, answerResponseUid, request.Text));
+            return Ok(answerResponse.ToAnswerResponseQuestionStateResponse());
+        }
     }
 }
Index: src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswersController.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswersController.cs	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswersController.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -32,4 +32,12 @@
         }
 
+        [HttpPut("{answerUid:Guid}")]
+        [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthenticationPolicy.Student)]
+        public async Task<IActionResult> EditAnswer([FromRoute] Guid questionUid, [FromRoute] Guid answerUid, [FromBody] AnswerQuestionRequest request)
+        {
+            var answer = await MediatorService.SendAsync(new EditAnswerCommand(questionUid, answerUid, request.Text));
+            return Ok(answer.ToAnswerQuestionStateResponse());
+        }
+
         [HttpPut("{answerUid:Guid}/correct")]
         [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthenticationPolicy.Student)]
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswer/EditAnswerCommand.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswer/EditAnswerCommand.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswer/EditAnswerCommand.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,63 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Common.Mediator.Interfaces;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.Repositories.Contracts;
+using FinkiChattery.Persistence.UnitOfWork;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class EditAnswerCommand : ICommand<AnswerQuestionStateDto>
+    {
+        public EditAnswerCommand(Guid questionUid, Guid answerUid, string text)
+        {
+            QuestionUid = questionUid;
+            AnswerUid = answerUid;
+            Text = text;
+        }
+
+        public Guid QuestionUid { get; }
+        public Guid AnswerUid { get; }
+        public string Text { get; }
+    }
+
+    public class EditAnswerHandler : ICommandHandler<EditAnswerCommand, AnswerQuestionStateDto>
+    {
+        public EditAnswerHandler(IUnitOfWork unitOfWork, ICurrentUser currentUser, IEventService eventService)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+            EventService = eventService;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+        public IEventService EventService { get; }
+
+        public async Task<AnswerQuestionStateDto> Handle(EditAnswerCommand request, CancellationToken cancellationToken)
+        {
+            var answer = await UnitOfWork.Answers.GetByUidAsync(request.AnswerUid);
+            var student = await UnitOfWork.Students.GetStudent(CurrentUser.Id);
+
+            answer.Text = request.Text;
+
+            await UnitOfWork.SaveAsync();
+
+            return new AnswerQuestionStateDto(answer.Id,
+                                              answer.Uid,
+                                              answer.Text,
+                                              answer.CorrectAnswer,
+                                              answer.CreatedOn,
+                                              answer.VotesCount,
+                                              new AnswerStudentQuestionStateDto(student.Id,
+                                                                                student.Uid,
+                                                                                student.IndexNumber,
+                                                                                student.ImageUrl,
+                                                                                student.Reputation),
+                                              Enumerable.Empty<AnswerResponseQuestionStateDto>());
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswer/EditAnswerValidator.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswer/EditAnswerValidator.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswer/EditAnswerValidator.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,20 @@
+﻿using FinkiChattery.Commands.Questioning.Validators;
+using FinkiChattery.Commands.Questioning.Validators.Contracts;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class EditAnswerValidator : AbstractValidator<EditAnswerCommand>
+    {
+        public EditAnswerValidator(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            CascadeMode = CascadeMode.Stop;
+
+            RuleFor(x => x.Text).AnswerTextValidate();
+            RuleFor(x => new AnswerInQuestionWithUidExistsDto(x.QuestionUid, x.AnswerUid)).SetValidator(new AnswerInQuestionWithUidExists(unitOfWork));
+            RuleFor(x => x.AnswerUid).SetValidator(new StudentIsOwnerOfAnswer(unitOfWork, currentUser));
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswerResponse/EditAnswerResponseCommand.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswerResponse/EditAnswerResponseCommand.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswerResponse/EditAnswerResponseCommand.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,58 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.Repositories.Contracts;
+using FinkiChattery.Persistence.UnitOfWork;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class EditAnswerResponseCommand : ICommand<AnswerResponseQuestionStateDto>
+    {
+        public EditAnswerResponseCommand(Guid questionUid, Guid answerUid, Guid answerResponseUid, string text)
+        {
+            QuestionUid = questionUid;
+            AnswerUid = answerUid;
+            AnswerResponseUid = answerResponseUid;
+            Text = text;
+        }
+
+        public Guid QuestionUid { get; }
+        public Guid AnswerUid { get; }
+        public Guid AnswerResponseUid { get; }
+        public string Text { get; }
+    }
+
+    public class EditAnswerResponseHandler : ICommandHandler<EditAnswerResponseCommand, AnswerResponseQuestionStateDto>
+    {
+        public EditAnswerResponseHandler(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+
+        public async Task<AnswerResponseQuestionStateDto> Handle(EditAnswerResponseCommand request, CancellationToken cancellationToken)
+        {
+            var answerResponse = await UnitOfWork.AnswerResponses.GetByUidAsync(request.AnswerResponseUid);
+            var student = await UnitOfWork.Students.GetStudent(CurrentUser.Id);
+
+            answerResponse.Text = request.Text;
+
+            await UnitOfWork.SaveAsync();
+
+            return new AnswerResponseQuestionStateDto(answerResponse.Id,
+                                                      answerResponse.Uid,
+                                                      answerResponse.Text,
+                                                      answerResponse.CreatedOn,
+                                                      new AnswerResponseStudentQuestionStateDto(student.Id,
+                                                                                                student.Uid,
+                                                                                                student.IndexNumber,
+                                                                                                student.ImageUrl,
+                                                                                                student.Reputation));
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswerResponse/EditAnswerResponseValidator.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswerResponse/EditAnswerResponseValidator.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/EditAnswerResponse/EditAnswerResponseValidator.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,20 @@
+﻿using FinkiChattery.Commands.Questioning.Validators;
+using FinkiChattery.Commands.Questioning.Validators.Contracts;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class EditAnswerResponseValidator : AbstractValidator<EditAnswerResponseCommand>
+    {
+        public EditAnswerResponseValidator(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            CascadeMode = CascadeMode.Stop;
+
+            RuleFor(x => x.Text).AnswerResponseTextValidate();
+            RuleFor(x => new AnswerInQuestionWithUidExistsDto(x.QuestionUid, x.AnswerUid)).SetValidator(new AnswerInQuestionWithUidExists(unitOfWork));
+            RuleFor(x => x.AnswerResponseUid).SetValidator(new StudentIsOwnerOfAnswerResponse(unitOfWork, currentUser));
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -17,4 +17,6 @@
         public const string AnswerInQuestionNotFound = "AnswerInQuestionNotFound"; 
         public const string StudentDoesNotOwnQuestion = "StudentDoesNotOwnQuestion";
+        public const string StudentDoesNotOwnAnswer = "StudentDoesNotOwnAnswer";
+        public const string StudentDoesNotOwnAnswerResponse = "StudentDoesNotOwnAnswerResponse";
         public const string AnswerIsAlreadyMarkedAsCorrect = "AnswerIsAlreadyMarkedAsCorrect";
     }
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfAnswer.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfAnswer.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfAnswer.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,33 @@
+﻿using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation.Validators;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning.Validators
+{
+    public class StudentIsOwnerOfAnswer : AsyncValidatorBase
+    {
+        public StudentIsOwnerOfAnswer(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+
+        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
+        {
+            var answerUid = (Guid)context.PropertyValue;
+
+            return await UnitOfWork.Answers.AnswerIsOwnedByStudent(answerUid, CurrentUser.Id);
+        }
+
+        protected override string GetDefaultMessageTemplate()
+        {
+            return QuestioningErrorCodes.StudentDoesNotOwnAnswer;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfAnswerResponse.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfAnswerResponse.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfAnswerResponse.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -0,0 +1,33 @@
+﻿using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation.Validators;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning.Validators
+{
+    public class StudentIsOwnerOfAnswerResponse : AsyncValidatorBase
+    {
+        public StudentIsOwnerOfAnswerResponse(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+
+        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
+        {
+            var answerResponseUid = (Guid)context.PropertyValue;
+
+            return await UnitOfWork.AnswerResponses.StudentIsOwnerOfAnswerResponse(answerResponseUid, CurrentUser.Id);
+        }
+
+        protected override string GetDefaultMessageTemplate()
+        {
+            return QuestioningErrorCodes.StudentDoesNotOwnAnswerResponse;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerRepo.cs	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerRepo.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -8,4 +8,6 @@
     {
         Task<bool> AnswerInQuestionExists(Guid questionUid, Guid answerUid);
+
+        Task<bool> AnswerIsOwnedByStudent(Guid answerUid, long applicationUserId);
     }
 }
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerResponseRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerResponseRepo.cs	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerResponseRepo.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -1,3 +1,5 @@
 ﻿using FinkiChattery.Persistence.Models;
+using System;
+using System.Threading.Tasks;
 
 namespace FinkiChattery.Persistence.Repositories
@@ -5,4 +7,5 @@
     public interface IAnswerResponseRepo : IRepository<AnswerResponse>
     {
+        Task<bool> StudentIsOwnerOfAnswerResponse(Guid answerResponseUid, long applicationUserId);
     }
 }
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerRepo.cs	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerRepo.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -21,4 +21,12 @@
                 .AnyAsync();
         }
+
+        public async Task<bool> AnswerIsOwnedByStudent(Guid answerUid, long applicationUserId)
+        {
+            return await DbSet
+                .AsNoTracking()
+                .Where(x => x.Uid == answerUid && x.Student.ApplicationUserFk == applicationUserId)
+                .AnyAsync();
+        }
     }
 }
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerResponseRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerResponseRepo.cs	(revision 74ad056f091c70ce137fdc5adf1a93be84a6621f)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerResponseRepo.cs	(revision 9df3069cb12bbfe76a9c6acbb659c84b4fdc33b0)
@@ -1,4 +1,8 @@
 ﻿using FinkiChattery.Persistence.Context;
 using FinkiChattery.Persistence.Models;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
 
 namespace FinkiChattery.Persistence.Repositories
@@ -9,4 +13,12 @@
         {
         }
+
+        public async Task<bool> StudentIsOwnerOfAnswerResponse(Guid answerResponseUid, long applicationUserId)
+        {
+            return await DbSet
+                .AsNoTracking()
+                .Where(x => x.Uid == answerResponseUid && x.Student.ApplicationUserFk == applicationUserId)
+                .AnyAsync();
+        }
     }
 }
