1
+ const BASE_URL = "https://www.themealdb.com/api/json/v1/1/" ;
2
+
3
+ const randRecipeName = document . querySelector ( '#rand-recipe-name' ) ;
4
+ const randRecipeImg = document . querySelector ( '#rand-recipe-img' ) ;
5
+ const addFavorite = document . querySelector ( '.add-favorite' ) ;
6
+ const recipeModal = document . querySelector ( '.recipe-modal' ) ;
7
+ const closeModal = document . querySelector ( '.close-modal' ) ;
8
+ const cardImg = document . querySelector ( '.card .card-img-top' )
9
+ const card = document . querySelector ( '.card' ) ;
10
+ const recipeModalList = document . querySelector ( '.recipe-modal-list' ) ;
11
+ const favoriteMealField = document . querySelector ( '.favorite-meal' ) ;
12
+ const mealTable = document . querySelector ( ".meal-table" ) ;
13
+ const searchBar = document . querySelector ( "input[type='text']" ) ;
14
+
15
+ let randomRecipe = { }
16
+ let recipe = { }
17
+ let objectKeys = [ ] ;
18
+ let ingredients = [ ] ;
19
+ let amounts = [ ] ;
20
+ let favorites = [ ] ;
21
+ let otherCounter = 0 ;
22
+ let results = [ ] ;
23
+
24
+ const appendFavoritesToDocument = ( mealData ) => {
25
+ const mealImg = document . createElement ( 'img' ) ;
26
+ const mealNameTd = document . createElement ( 'td' ) ;
27
+ const th = document . createElement ( 'th' ) ;
28
+
29
+ mealImg . setAttribute ( 'id' , 'favorite-meal-img' ) ;
30
+ mealImg . src = mealData . strMealThumb ;
31
+ mealNameTd . innerHTML = `<td>${ mealData . strMeal } </td>` ;
32
+
33
+ th . setAttribute ( 'class' , 'favorite-meal-img' ) ;
34
+ th . setAttribute ( 'value' , mealData . idMeal ) ;
35
+ mealNameTd . setAttribute ( 'class' , "favorite-meal-name" ) ;
36
+ mealNameTd . setAttribute ( 'value' , mealData . idMeal ) ;
37
+ th . appendChild ( mealImg ) ;
38
+
39
+ document . querySelector ( '.meal-images' ) . appendChild ( th ) ;
40
+ document . querySelector ( '.meal-names' ) . appendChild ( mealNameTd ) ;
41
+ }
42
+
43
+ const getFavorites = async ( ) => {
44
+ JSON . parse ( localStorage . getItem ( 'favorites' ) ) . forEach ( async ( item ) => {
45
+ const fetchData = await axios . get ( BASE_URL + `lookup.php?i=${ item } ` ) ;
46
+ const mealData = fetchData . data . meals [ 0 ] ;
47
+ appendFavoritesToDocument ( mealData ) ;
48
+ } ) ;
49
+ }
50
+
51
+ const addToFavorites = async ( id ) => {
52
+ const fetchData = await axios . get ( BASE_URL + `lookup.php?i=${ id } ` ) ;
53
+ const mealData = fetchData . data . meals [ 0 ] ;
54
+ appendFavoritesToDocument ( mealData ) ;
55
+ }
56
+
57
+ window . onload = async ( ) => {
58
+ if ( ! localStorage . getItem ( 'favorites' ) ) {
59
+ localStorage . setItem ( 'favorites' , JSON . stringify ( favorites ) ) ;
60
+ }
61
+
62
+ if ( localStorage . getItem ( 'favorites' ) . length > 0 ) {
63
+ getFavorites ( ) ;
64
+ }
65
+ }
66
+
67
+ const getRandomRecipe = async ( ) => {
68
+ const randRecipe = await axios . get ( BASE_URL + "random.php" ) ;
69
+ randomRecipe = { ...randRecipe . data . meals [ 0 ] } ;
70
+
71
+ card . setAttribute ( 'value' , randomRecipe . idMeal ) ;
72
+ randRecipeName . innerHTML = `<span class="recipe-name" id="rand-recipe-name">${ randomRecipe . strMeal } <span class="add-favorite" id="addFavorite"><svg width="1.5em" height="1.5em" viewBox="0 0 16 16" class="bi bi-heart-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
73
+ <path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>
74
+ </svg></span></span>` ;
75
+ randRecipeImg . src = `${ randomRecipe . strMealThumb } ` ;
76
+ }
77
+
78
+ const getRecipeById = async ( id ) => {
79
+ const favoriteId = JSON . parse ( localStorage . getItem ( 'favorites' ) ) ; // For Comparison with favorite recipe
80
+ recipeModal . style . display = "block" ;
81
+ const getById = await axios . get ( BASE_URL + `lookup.php?i=${ id } ` ) ;
82
+ recipe = getById . data . meals [ 0 ] ;
83
+ objectKeys = [ ...Object . keys ( recipe ) ] ; //objectKeys[9] = "strIngredient1", objectKeys[48] = "strMeasure20"
84
+
85
+ //========= FOR ONLY GETTING INGREDIENTS AND AMOUNT OF INDGREDIENTS =============
86
+ let extractKeys = [ ] ;
87
+
88
+ for ( var i = 9 ; i <= 48 ; i ++ ) {
89
+ extractKeys . push ( objectKeys [ i ] ) ;
90
+ }
91
+ //========= FOR ONLY GETTING INGREDIENTS AND AMOUNT OF INDGREDIENTS =============
92
+
93
+ let ingredientsAndAmounts = [ ]
94
+
95
+ //remove empty ingredients and amounts
96
+ extractKeys . forEach ( ( item ) => {
97
+ return recipe [ item ] == "" || recipe [ item ] == null || recipe [ item ] == " " ? "" : ingredientsAndAmounts . push ( recipe [ item ] ) ;
98
+ } ) ;
99
+
100
+ //Only Get Ingredients
101
+ for ( let i = 0 ; i < ( ingredientsAndAmounts . length / 2 ) ; i ++ ) {
102
+ ingredients . push ( ingredientsAndAmounts [ i ] ) ;
103
+ }
104
+
105
+ //Only Get Amounts
106
+ for ( let i = ingredientsAndAmounts . length / 2 ; i < ingredientsAndAmounts . length ; i ++ ) {
107
+ amounts . push ( ingredientsAndAmounts [ i ] ) ;
108
+ }
109
+
110
+ for ( let i = 0 ; i < ingredients . length ; i ++ ) {
111
+ const newLi = document . createElement ( 'li' ) ;
112
+ newLi . innerHTML = `<span id="amount">${ amounts [ i ] } </span> <span id="ingredient">${ ingredients [ i ] } </span>` ;
113
+
114
+ newLi . setAttribute ( 'class' , 'pb-3' ) ;
115
+ recipeModalList . appendChild ( newLi ) ;
116
+
117
+ }
118
+
119
+ document . querySelector ( '#recipe-modal-img' ) . src = recipe . strMealThumb ;
120
+ document . querySelector ( '#recipe-modal-name' ) . innerHTML = `<span class="recipe-name" id="recipe-modal-name">${ recipe . strMeal } </span>` ;
121
+ document . querySelector ( '#recipe-modal-instructions' ) . innerText = recipe . strInstructions ;
122
+ }
123
+
124
+ const addFavoriteEvent = async ( id ) => {
125
+ const fetchData = await axios . get ( BASE_URL + `lookup.php?i=${ id } ` ) ;
126
+ const mealData = fetchData . data . meals [ 0 ] ;
127
+
128
+ let temp = 0 ; //Counter for duplicates in array
129
+ favorites = [ ...JSON . parse ( localStorage . getItem ( 'favorites' ) ) ] ;
130
+
131
+ favorites . forEach ( ( item ) => {
132
+ if ( item == id ) {
133
+ temp ++ ;
134
+ }
135
+ } ) ;
136
+
137
+ if ( temp <= 0 ) {
138
+ favorites . push ( id ) ;
139
+ localStorage . setItem ( 'favorites' , JSON . stringify ( favorites ) ) ;
140
+ } else {
141
+ favorites . splice ( favorites . indexOf ( id ) , 1 ) ;
142
+ localStorage . setItem ( 'favorites' , JSON . stringify ( favorites ) ) ;
143
+ }
144
+
145
+ if ( otherCounter % 2 != 0 ) {
146
+ document . querySelector ( '.add-favorite svg' ) . style . color = "black" ;
147
+ document . querySelector ( '.card .recipe-name .add-favorite svg' ) . style . color = "black" ;
148
+ } else {
149
+ document . querySelector ( '.add-favorite svg' ) . style . color = "gray" ;
150
+ document . querySelector ( '.card .recipe-name .add-favorite svg' ) . style . color = "gray" ;
151
+ }
152
+ }
153
+
154
+ document . querySelector ( '.card .recipe-name' ) . addEventListener ( "click" , ( event ) => {
155
+ otherCounter ++ ;
156
+ if ( event . target . className == '[object SVGAnimatedString]' ) {
157
+ makeFavsVisible ( ) ;
158
+ }
159
+ } ) ;
160
+
161
+ function makeFavsVisible ( ) {
162
+ addFavoriteEvent ( card . getAttribute ( 'value' ) ) ;
163
+ let counter = 0 ;
164
+ const favs = document . querySelector ( ".meal-images" ) . childNodes ;
165
+ const favMealNames = document . querySelector ( ".meal-names" ) . childNodes ;
166
+ for ( let i = 1 ; i < favs . length ; i ++ ) {
167
+ if ( favs [ i ] . getAttribute ( 'value' ) != card . getAttribute ( 'value' ) ) {
168
+ counter ++ ;
169
+ } else {
170
+ favs [ i ] . style . display = 'none' ;
171
+ favMealNames [ i ] . style . display = 'none' ;
172
+ }
173
+ }
174
+
175
+ if ( otherCounter % 2 != 0 ) {
176
+ addToFavorites ( card . getAttribute ( 'value' ) ) ;
177
+ } else {
178
+ document . querySelector ( '.add-favorite svg' ) . style . color = "pink" ;
179
+ }
180
+ }
181
+
182
+ closeModal . addEventListener ( 'click' , ( ) => {
183
+ recipeModal . style . display = 'none' ;
184
+ } ) ;
185
+
186
+ document . querySelector ( '.meal-images' ) . addEventListener ( "click" , ( e ) => {
187
+ if ( Object . is ( document . querySelector ( 'th img' ) . id , e . target . id ) ) {
188
+ getRecipeById ( e . target . parentNode . getAttribute ( 'value' ) ) ;
189
+ }
190
+ } ) ;
191
+
192
+ document . querySelector ( '.search-icon' ) . addEventListener ( 'click' , async ( ) => {
193
+ axios
194
+ . get ( BASE_URL + `search.php?s=${ searchBar . value } ` )
195
+ . then ( result => {
196
+ return result . data . meals ;
197
+ } )
198
+ . then ( data => {
199
+ if ( data ) {
200
+ document . querySelectorAll ( '.content .card' ) . forEach ( element => {
201
+ element . style . display = 'none' ;
202
+ } ) ;
203
+
204
+ data . forEach ( item => {
205
+ const div = document . createElement ( 'div' ) ;
206
+ div . setAttribute ( 'value' , item . idMeal ) ;
207
+ div . setAttribute ( 'class' , 'card random-recipe mb-4 mt-4' ) ;
208
+ div . style . width = "90%" ;
209
+
210
+ const img = document . createElement ( 'img' ) ;
211
+ img . setAttribute ( 'class' , "card-img-top recipe-img" ) ;
212
+ img . setAttribute ( 'id' , "rand-recipe-img" )
213
+ img . setAttribute ( 'src' , item . strMealThumb ) ;
214
+ img . setAttribute ( 'alt' , item . strMeal ) ;
215
+ img . setAttribute ( 'onclick' , `getRecipeById(${ item . idMeal } )` ) ;
216
+
217
+ const p = document . createElement ( 'p' ) ;
218
+ p . setAttribute ( 'class' , 'lead' ) ;
219
+ p . innerHTML = "Results" ;
220
+
221
+ const span = document . createElement ( 'span' ) ;
222
+ span . setAttribute ( 'class' , 'recipe-name' ) ;
223
+ span . setAttribute ( 'id' , 'rand-recipe-name' ) ;
224
+ span . innerHTML = `<span class="recipe-name" id="rand-recipe-name">${ item . strMeal } <span class="add-favorite" id="addFavorite" onclick="makeFavsVisible()"><svg width="1.5em" height="1.5em" viewBox="0 0 16 16" class="bi bi-heart-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
225
+ <path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>
226
+ </svg></span></span>`
227
+
228
+ div . appendChild ( img ) ;
229
+ div . appendChild ( p ) ;
230
+ div . appendChild ( span ) ;
231
+
232
+ document . querySelector ( '.content' ) . appendChild ( div ) ;
233
+ } ) ;
234
+ } else {
235
+ alert ( 'No Recipe Found' ) ;
236
+ }
237
+ } )
238
+
239
+ } ) ;
240
+
241
+ cardImg . addEventListener ( 'click' , ( e ) => {
242
+ if ( e . target . tagName . toLowerCase ( ) === 'img' ) {
243
+ getRecipeById ( card . getAttribute ( 'value' ) ) ;
244
+ }
245
+ } ) ;
246
+
247
+ getRandomRecipe ( ) ;
0 commit comments