Skip to content

Commit 00cc7b7

Browse files
author
Vlad Sandu
committed
Add support for inserting todo items and refactor code
1 parent 4e4ad05 commit 00cc7b7

12 files changed

+111
-14
lines changed

TodoApp.DTO/TodoItemDto.cs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
{
33
public class TodoItemDto
44
{
5-
public int UserId { get; set; }
65
public string Description { get; set; }
76
}
87
}

TodoApp.Services/TodoItem/TodoItemService.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ public IEnumerable<TodoItemDto> Get(string email)
2222
.Select(t => Mapper.Map<TodoItem, TodoItemDto>(t)).ToList();
2323
}
2424

25-
public void Add(TodoItemDto todoItemDto, UserDto userDto)
25+
public void Add(TodoItemDto todoItemDto, string email)
2626
{
27-
var user = GetUser(userDto);
27+
var user = GetUser(email);
2828
_dbContext.Add(new TodoItem
2929
{
3030
Description = todoItemDto.Description,
@@ -33,9 +33,9 @@ public void Add(TodoItemDto todoItemDto, UserDto userDto)
3333
_dbContext.SaveChanges();
3434
}
3535

36-
public void Remove(TodoItemDto todoItemDto, UserDto userDto)
36+
public void Remove(TodoItemDto todoItemDto, string email)
3737
{
38-
var user = GetUser(userDto);
38+
var user = GetUser(email);
3939
_dbContext.Remove(new TodoItem
4040
{
4141
Description = todoItemDto.Description,
@@ -44,9 +44,9 @@ public void Remove(TodoItemDto todoItemDto, UserDto userDto)
4444
_dbContext.SaveChanges();
4545
}
4646

47-
private User GetUser(UserDto userDto)
47+
private User GetUser(string email)
4848
{
49-
return _dbContext.User.First(u => u.Email == userDto.Email);
49+
return _dbContext.User.First(u => u.Email == email);
5050
}
5151
}
5252
}

TodoApp/ClientApp/src/app/app.module.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ import { AuthGuard } from './guards/auth.guard';
1717
import { TodoItemService } from "./services/todoitem.service";
1818
import { TodoItemComponent } from './todo-item/todo-item.component';
1919
import { TodoListComponent } from './todo-list/todo-list.component';
20-
21-
@
22-
NgModule({
20+
import { TodoItemInserterComponent } from './todo-item-inserter/todo-item-inserter.component';
21+
@NgModule({
2322
declarations: [
2423
AppComponent,
2524
NavMenuComponent,
@@ -28,7 +27,8 @@ NgModule({
2827
RegisterComponent,
2928
LogoutComponent,
3029
TodoItemComponent,
31-
TodoListComponent
30+
TodoListComponent,
31+
TodoItemInserterComponent
3232
],
3333
imports: [
3434
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),

TodoApp/ClientApp/src/app/layouts/home-layout.component.html

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
</div>
66
<div class="col-sm-9" body-content>
77
<todo-list [items]="todoItems | async"></todo-list>
8+
<todo-item-inserter (shouldRefreshItems)="refreshItems()"></todo-item-inserter>
89
</div>
910
</div>
1011
</div>

TodoApp/ClientApp/src/app/layouts/home-layout.component.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@ export class HomeLayoutComponent implements AfterViewInit {
1010
todoItems: Observable<TodoItem[]>;
1111

1212
constructor(private readonly todoItemService: TodoItemService) {
13-
this.todoItems = this.todoItemService.get();
13+
this.refreshItems();
1414
}
1515

1616
ngAfterViewInit(): void {
1717

1818
}
1919

20+
refreshItems() {
21+
// TODO: Improve this
22+
this.todoItems = this.todoItemService.get() as any;
23+
}
2024
}

TodoApp/ClientApp/src/app/services/todoitem.service.ts

+8
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,12 @@ export class TodoItemService {
1616
return throwError(err);
1717
}));
1818
}
19+
20+
post(todoItem: TodoItem) {
21+
return this.http.post('/api/todoitem', todoItem)
22+
.pipe(
23+
catchError(err => {
24+
return throwError(err);
25+
}));
26+
}
1927
}

TodoApp/ClientApp/src/app/todo-item-inserter/todo-item-inserter.component.css

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div class="container">
2+
<h1>Add a Todo item:</h1>
3+
<form>
4+
<div class="form-group">
5+
<label for="description">Description:</label>
6+
<input type="text" class="form-control" id="description" #description required>
7+
</div>
8+
9+
<button type="submit" class="btn btn-success" (click)="insertTodo(description.value)">Submit</button>
10+
</form>
11+
</div>
12+
<div>{{resultMessage}}</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { TodoItemInserterComponent } from './todo-item-inserter.component';
4+
5+
describe('TodoItemInserterComponent', () => {
6+
let component: TodoItemInserterComponent;
7+
let fixture: ComponentFixture<TodoItemInserterComponent>;
8+
9+
beforeEach(async(() => {
10+
TestBed.configureTestingModule({
11+
declarations: [TodoItemInserterComponent ]
12+
})
13+
.compileComponents();
14+
}));
15+
16+
beforeEach(() => {
17+
fixture = TestBed.createComponent(TodoItemInserterComponent);
18+
component = fixture.componentInstance;
19+
fixture.detectChanges();
20+
});
21+
22+
it('should create', () => {
23+
expect(component).toBeTruthy();
24+
});
25+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
2+
import { TodoItemService } from "../services/todoitem.service";
3+
import { catchError } from 'rxjs/operators';
4+
import { throwError } from 'rxjs';
5+
6+
@Component({
7+
selector: 'todo-item-inserter',
8+
templateUrl: './todo-item-inserter.component.html',
9+
styleUrls: ['./todo-item-inserter.component.css']
10+
})
11+
export class TodoItemInserterComponent implements OnInit {
12+
@Output() shouldRefreshItems = new EventEmitter<void>();
13+
resultMessage: string;
14+
15+
constructor(private readonly todoItemService: TodoItemService) { }
16+
17+
ngOnInit() {
18+
}
19+
20+
insertTodo(description: string) {
21+
const todoItem = { description };
22+
this.todoItemService.post(todoItem).pipe(
23+
catchError(err => {
24+
this.resultMessage = err.message;
25+
return throwError(err);
26+
}))
27+
.subscribe(() => {
28+
this.resultMessage = "Message inserted successfully!";
29+
this.shouldRefreshItems.emit();
30+
});
31+
}
32+
}

TodoApp/Controllers/TodoItemController.cs

+16
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,21 @@ public IActionResult Get()
3232
return StatusCode(500);
3333
}
3434
}
35+
36+
[HttpPost]
37+
public IActionResult Post(TodoItemDto todoItemDto)
38+
{
39+
try
40+
{
41+
var email = User.FindFirst(ClaimTypes.Email).Value;
42+
_todoItemService.Add(todoItemDto, email);
43+
return Ok();
44+
}
45+
catch (Exception e)
46+
{
47+
Console.WriteLine(e.Message);
48+
return StatusCode(500);
49+
}
50+
}
3551
}
3652
}

TodoApp/TodoApp.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk.Web">
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp2.1</TargetFramework>
@@ -7,7 +7,7 @@
77
<IsPackable>false</IsPackable>
88
<SpaRoot>ClientApp\</SpaRoot>
99
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
10-
10+
<TypeScriptExperimentalDecorators>true</TypeScriptExperimentalDecorators>
1111
<!-- Set this to true if you enable server-side prerendering -->
1212
<BuildServerSideRenderer>false</BuildServerSideRenderer>
1313
<UserSecretsId>8aa6639e-8cfa-4b13-8ae4-9f0744c398f8</UserSecretsId>

0 commit comments

Comments
 (0)