﻿1
00:00:01,210 --> 00:00:02,660
‫So far in this section,

2
00:00:02,660 --> 00:00:04,860
‫we have talked about Mongoose models,

3
00:00:04,860 --> 00:00:06,940
‫CRUD operations with Mongoose,

4
00:00:06,940 --> 00:00:09,660
‫we did a lot of querying, and we learned about

5
00:00:09,660 --> 00:00:12,820
‫the aggregation pipeline, but now for the next

6
00:00:12,820 --> 00:00:15,110
‫couple of videos, let's actually return

7
00:00:15,110 --> 00:00:18,860
‫to our data model and learn some super useful features

8
00:00:18,860 --> 00:00:22,170
‫that Mongoose offers us in order to model our data.

9
00:00:22,170 --> 00:00:24,090
‫And the first one we're gonna talk about

10
00:00:24,090 --> 00:00:25,773
‫are virtual properties.

11
00:00:27,410 --> 00:00:29,973
‫And so let's open our tour model here.

12
00:00:31,050 --> 00:00:35,080
‫All right, now virtual properties are basically fields

13
00:00:35,080 --> 00:00:37,030
‫that we can define on our schema

14
00:00:37,030 --> 00:00:39,150
‫but that will not be persisted.

15
00:00:39,150 --> 00:00:42,100
‫So they will not be saved into the database

16
00:00:42,100 --> 00:00:44,720
‫in order to save us some space there.

17
00:00:44,720 --> 00:00:46,140
‫And most of the time, of course,

18
00:00:46,140 --> 00:00:49,260
‫we want to really save our data to the database,

19
00:00:49,260 --> 00:00:51,700
‫but virtual properties make a lot of sense

20
00:00:51,700 --> 00:00:55,090
‫for fields that can be derived from one another.

21
00:00:55,090 --> 00:00:58,410
‫For example a conversion from miles to kilometers,

22
00:00:58,410 --> 00:01:00,720
‫it doesn't make sense to store these two fields

23
00:01:00,720 --> 00:01:03,260
‫in a database if we can easily convert

24
00:01:03,260 --> 00:01:05,750
‫one to the other, right?

25
00:01:05,750 --> 00:01:09,140
‫Okay, so let's now define a virtual property

26
00:01:09,140 --> 00:01:11,680
‫that contains the tour duration in weeks.

27
00:01:11,680 --> 00:01:13,800
‫And so that's a field basically

28
00:01:13,800 --> 00:01:16,460
‫that we can very easily convert from the duration

29
00:01:16,460 --> 00:01:18,970
‫that we already have in days, right?

30
00:01:18,970 --> 00:01:20,523
‫And so here is how it works.

31
00:01:22,160 --> 00:01:25,640
‫We define that virtual properties on the tour schema,

32
00:01:25,640 --> 00:01:30,640
‫and so we say, tourSchema.virtual and then the name

33
00:01:33,430 --> 00:01:34,763
‫of the virtual property.

34
00:01:36,530 --> 00:01:39,300
‫So let's call it duration weeks,

35
00:01:39,300 --> 00:01:42,950
‫and then on there we need to define the get method.

36
00:01:42,950 --> 00:01:45,600
‫And that's just because this virtual property here

37
00:01:45,600 --> 00:01:47,580
‫will basically be created each time

38
00:01:47,580 --> 00:01:50,560
‫that we get some data out of the database.

39
00:01:50,560 --> 00:01:54,273
‫And so this get function here is called a getter.

40
00:01:54,273 --> 00:01:57,090
‫Now in here we pass a function,

41
00:01:57,090 --> 00:01:58,400
‫and actually this call back function

42
00:01:58,400 --> 00:02:02,460
‫is gonna be a real function, so not an arrow function,

43
00:02:02,460 --> 00:02:05,672
‫and I'm gonna explain to you why in a second.

44
00:02:05,672 --> 00:02:08,500
‫Now how do we then basically define

45
00:02:08,500 --> 00:02:10,810
‫the virtual property?

46
00:02:10,810 --> 00:02:13,420
‫Well it's very simple, all we have to say

47
00:02:13,420 --> 00:02:18,280
‫is that we want to return this, .duration in this case,

48
00:02:18,280 --> 00:02:19,833
‫divided by seven.

49
00:02:21,020 --> 00:02:24,350
‫So this is how we calculate the duration in weeks,

50
00:02:24,350 --> 00:02:26,730
‫so the duration in days divided by seven

51
00:02:26,730 --> 00:02:29,110
‫because there are seven days in the week,

52
00:02:29,110 --> 00:02:31,030
‫and so that's then the duration in weeks.

53
00:02:31,030 --> 00:02:33,510
‫For example, if a tour has seven days,

54
00:02:33,510 --> 00:02:35,730
‫then it's of course gonna be one week.

55
00:02:35,730 --> 00:02:38,360
‫Now I used this regular function here

56
00:02:38,360 --> 00:02:41,250
‫because remember, an arrow function does not get

57
00:02:41,250 --> 00:02:43,060
‫its own disk keyword.

58
00:02:43,060 --> 00:02:45,800
‫In here we actually need the disk keyword

59
00:02:45,800 --> 00:02:48,470
‫because the disk keyword in this case

60
00:02:48,470 --> 00:02:51,588
‫is going to be pointing to the current document.

61
00:02:51,588 --> 00:02:54,640
‫And so usually when we want to use this,

62
00:02:54,640 --> 00:02:58,714
‫then we should always use a regular function.

63
00:02:58,714 --> 00:03:01,140
‫So really everywhere in Mongoose,

64
00:03:01,140 --> 00:03:04,340
‫I'm gonna always be using these regular functions

65
00:03:04,340 --> 00:03:06,061
‫that we're used to.

66
00:03:06,061 --> 00:03:11,061
‫So give it a save here, and that's actually it.

67
00:03:11,070 --> 00:03:13,180
‫That's how we define duration weeks,

68
00:03:13,180 --> 00:03:15,660
‫which is not going to be persisted in the database,

69
00:03:15,660 --> 00:03:19,150
‫but it's only gonna be there as soon as we get the data.

70
00:03:19,150 --> 00:03:21,820
‫Now right now it's actually not gonna be there yet,

71
00:03:21,820 --> 00:03:24,610
‫because there's one piece missing here,

72
00:03:24,610 --> 00:03:27,243
‫so let me start by showing you that.

73
00:03:28,760 --> 00:03:31,240
‫So if we try to get all tours,

74
00:03:31,240 --> 00:03:34,050
‫you will see that duration weeks is nowhere

75
00:03:34,050 --> 00:03:35,768
‫to be found here.

76
00:03:35,768 --> 00:03:38,660
‫And that's because we need to explicitly define

77
00:03:38,660 --> 00:03:41,740
‫in our schema that we want the virtual properties

78
00:03:41,740 --> 00:03:42,683
‫in our output.

79
00:03:43,758 --> 00:03:48,758
‫And so remember how I said that into this Mongoose.schema,

80
00:03:49,320 --> 00:03:51,650
‫we can pass in not only the object

81
00:03:51,650 --> 00:03:54,050
‫with the schema definition itself,

82
00:03:54,050 --> 00:03:56,943
‫but also an object for the schema options.

83
00:03:58,070 --> 00:04:00,579
‫And so let's add that here at the end,

84
00:04:00,579 --> 00:04:04,810
‫so this first object here is the schema definition,

85
00:04:04,810 --> 00:04:07,630
‫and now second an object for the options.

86
00:04:07,630 --> 00:04:11,260
‫And what we need to specify here is the two JSON

87
00:04:12,390 --> 00:04:15,410
‫property here, and what we say is then

88
00:04:15,410 --> 00:04:19,453
‫that each time that the data is actually outputted as JSON,

89
00:04:20,480 --> 00:04:22,710
‫we want virtuals to be true.

90
00:04:23,681 --> 00:04:26,657
‫So basically the virtuals to be part of the output.

91
00:04:27,800 --> 00:04:30,000
‫And now I'm duplicating this because we also

92
00:04:30,000 --> 00:04:31,923
‫want to say to object.

93
00:04:33,370 --> 00:04:36,037
‫So basically when the data gets outputted

94
00:04:36,037 --> 00:04:37,320
‫as an object.

95
00:04:37,320 --> 00:04:40,010
‫And so if we now go back here, we should then

96
00:04:40,010 --> 00:04:41,993
‫be able to see duration weeks.

97
00:04:43,120 --> 00:04:46,550
‫Let's wait for it, and indeed, here it is.

98
00:04:46,550 --> 00:04:51,053
‫So it's five days, and so that is 0.71 weeks.

99
00:04:52,250 --> 00:04:55,800
‫Here we have seven days, and so that's one week.

100
00:04:55,800 --> 00:04:59,810
‫Okay, so that actually works, great.

101
00:04:59,810 --> 00:05:01,680
‫Now one thing that we need to keep in mind

102
00:05:01,680 --> 00:05:04,840
‫is that we cannot use this virtual property here

103
00:05:04,840 --> 00:05:07,840
‫in a query, because they're technically

104
00:05:07,840 --> 00:05:09,980
‫not part of the database.

105
00:05:09,980 --> 00:05:11,370
‫So we can not say, for example,

106
00:05:11,370 --> 00:05:16,370
‫tour.find where duration weeks is equal to one.

107
00:05:16,618 --> 00:05:19,660
‫That's not gonna work, again because this property

108
00:05:19,660 --> 00:05:22,520
‫is not actually part of the database.

109
00:05:22,520 --> 00:05:25,330
‫Now of course we could also have done this conversion

110
00:05:25,330 --> 00:05:28,450
‫each time after we query the data, for example,

111
00:05:28,450 --> 00:05:30,890
‫like in a controller, but that would not

112
00:05:30,890 --> 00:05:34,240
‫be the best practice simply because we want to try

113
00:05:34,240 --> 00:05:36,960
‫to keep business logic and application logic

114
00:05:36,960 --> 00:05:39,830
‫as much separated as possible, remember?

115
00:05:39,830 --> 00:05:42,980
‫So that was that whole talk about fat models

116
00:05:42,980 --> 00:05:46,950
‫and thin controllers that we talked about before

117
00:05:46,950 --> 00:05:48,850
‫which says that we should have models

118
00:05:48,850 --> 00:05:52,390
‫with as much business logic as we can offload to them

119
00:05:52,390 --> 00:05:54,460
‫and thin controllers with as little

120
00:05:54,460 --> 00:05:56,598
‫business logic as possible.

121
00:05:56,598 --> 00:05:59,840
‫And so virtual properties like this are actually

122
00:05:59,840 --> 00:06:01,970
‫a good example of how we can achieve

123
00:06:01,970 --> 00:06:03,483
‫that kind of architecture.

124
00:06:04,410 --> 00:06:06,460
‫So knowing the duration in weeks

125
00:06:06,460 --> 00:06:09,070
‫is a business logic because it has to do

126
00:06:09,070 --> 00:06:11,900
‫with the business itself, not with stuff like requests

127
00:06:11,900 --> 00:06:14,550
‫or responses, and so we do the calculation

128
00:06:14,550 --> 00:06:16,460
‫right in the model where it belongs

129
00:06:16,460 --> 00:06:17,863
‫and not in the controller.

