feat: add 'back/front end' in curriculum (#42596)

* chore: rename APIs and Microservices to include "Backend" (#42515)

* fix typo

* fix typo

* undo change

* Corrected grammar mistake

Corrected a grammar mistake by removing a comma.

* change APIs and Microservices cert title

* update title

* Change APIs and Microservices certi title

* Update translations.json

* update title

* feat(curriculum): rename apis and microservices cert

* rename folder structure

* rename certificate

* rename learn Markdown

* apis-and-microservices -> back-end-development-and-apis

* update backend meta

* update i18n langs and cypress test

Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>

* fix: add development to front-end libraries (#42512)

* fix: added-the-word-Development-to-front-end-libraries

* fix/added-the-word-Development-to-front-end-libraries

* fix/added-word-development-to-front-end-libraries-in-other-related-files

* fix/added-the-word-Development-to-front-end-and-all-related-files

* fix/removed-typos-from-last-commit-in-index.md

* fix/reverted-changes-that-i-made-to-dependecies

* fix/removed xvfg

* fix/reverted changes that i made to package.json

* remove unwanted changes

* front-end-development-libraries changes

* rename backend certSlug and README

* update i18n folder names and keys

* test: add legacy path redirect tests

This uses serve.json from the client-config repo, since we currently use
that in production

* fix: create public dir before moving serve.json

* fix: add missing script

* refactor: collect redirect tests

* test: convert to cy.location for stricter tests

* rename certificate folder to 00-certificates

* change crowdin config to recognise new certificates location

* allow translations to be used

Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>

* add forwards slashes to path redirects

* fix cypress path tests again

* plese cypress

* fix: test different challenge

Okay so I literally have no idea why this one particular challenge
fails in Cypress Firefox ONLY. Tom and I paired and spun a full build
instance and confirmed in Firefox the page loads and redirects as
expected. Changing to another bootstrap challenge passes Cypress firefox
locally. Absolutely boggled by this.

AAAAAAAAAAAAAAA

* fix: separate the test

Okay apparently the test does not work unless we separate it into
a different `it` statement.

>:( >:( >:( >:(

Co-authored-by: Sujal Gupta <55016909+heysujal@users.noreply.github.com>
Co-authored-by: Noor Fakhry <65724923+NoorFakhry@users.noreply.github.com>
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>
This commit is contained in:
Shaun Hamilton
2021-08-14 03:57:13 +01:00
committed by GitHub
parent 4df2a0c542
commit c2a11ad00d
1215 changed files with 790 additions and 449 deletions

View File

@ -0,0 +1,255 @@
---
id: 5a8b073d06fa14fcfde687aa
title: Monitor degli esercizi
challengeType: 4
forumTopicId: 301505
dashedName: exercise-tracker
---
# --description--
Costruisci un'app JavaScript full-stack che sia funzionalmente simile a questa: <https://exercise-tracker.freecodecamp.rocks/>. Lavorare su questo progetto ti porterà a scrivere il tuo codice utilizzando uno dei seguenti metodi:
- Clonare [questa repository GitHub](https://github.com/freeCodeCamp/boilerplate-project-exercisetracker/) e completa il tuo progetto localmente.
- Usare [la nostra bozza di progetto su Replit](https://replit.com/github/freeCodeCamp/boilerplate-project-exercisetracker) per completare il tuo progetto.
- Usare un costruttore di siti di tua scelta per completare il progetto. Assicurati di incorporare tutti i file della nostra repository GitHub.
Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata pubblicamente da qualche parte. Quindi invia l'URL nel campo `Solution Link`. Facoltativamente, invia anche un link al codice sorgente del tuo progetto nel campo `GitHub Link`.
# --hints--
Dovresti inviare il tuo progetto, non l'URL di esempio.
```js
(getUserInput) => {
const url = getUserInput('url');
assert(
!/.*\/exercise-tracker\.freecodecamp\.rocks/.test(getUserInput('url'))
);
};
```
Puoi fare una richiesta `POST` a `/api/users` con il dato `username` proveniente dal modulo per creare un nuovo utente. La risposta restituita sarà un oggetto con proprietà `username` e `_id`.
```js
async (getUserInput) => {
const url = getUserInput('url');
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
assert.exists(_id);
assert.exists(username);
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
È possibile fare una richiesta `GET` a `/api/users` per ottenere un array di tutti gli utenti. Ogni elemento nell'array è un oggetto contenente lo `username` e l'`_id` dell'utente.
```js
async (getUserInput) => {
const url = getUserInput('url');
const res = await fetch(url + '/api/users');
if (res.ok) {
const data = await res.json();
assert.isArray(data);
assert.isString(data[0].username);
assert.isString(data[0]._id);
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
È possibile fare una richiesta `POST` a `/api/users/:_id/exercises` con i dati del modulo `description`, `duration` e, facoltativamente `date`. Se non viene fornita alcuna data, verrà utilizzata la data corrente. La risposta restituita sarà l'oggetto utente con l'aggiunta dei campi dell'esercizio.
```js
async (getUserInput) => {
const url = getUserInput('url');
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
const expected = {
username,
description: 'test',
duration: 60,
_id,
date: 'Mon Jan 01 1990'
};
const addRes = await fetch(url + `/api/users/${_id}/exercises`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `description=${expected.description}&duration=${expected.duration}&date=1990-01-01`
});
if (addRes.ok) {
const actual = await addRes.json();
assert.deepEqual(actual, expected);
} else {
throw new Error(`${addRes.status} ${addRes.statusText}`);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
È possibile fare una richiesta `GET` a `/api/users/:_id/logs` per recuperare il log completo degli esercizi di qualsiasi utente. La risposta restituita sarà l'oggetto utente con un array `log` di tutti gli esercizi aggiunti. Ogni elemento di log ha le proprietà `description`, `duration` e `date`.
```js
async (getUserInput) => {
const url = getUserInput('url');
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
const expected = {
username,
description: 'test',
duration: 60,
_id,
date: new Date().toDateString()
};
const addRes = await fetch(url + `/api/users/${_id}/exercises`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `description=${expected.description}&duration=${expected.duration}`
});
if (addRes.ok) {
const logRes = await fetch(url + `/api/users/${_id}/logs`);
if (logRes.ok) {
const { log } = await logRes.json();
assert.isArray(log);
assert.equal(1, log.length);
} else {
throw new Error(`${logRes.status} ${logRes.statusText}`);
}
} else {
throw new Error(`${addRes.status} ${addRes.statusText}`);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
Una richiesta al log di un utente (`/api/users/:_id/logs`) restituisce un oggetto con una proprietà `count` che rappresenta il numero di esercizi restituiti.
```js
async (getUserInput) => {
const url = getUserInput('url');
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
const expected = {
username,
description: 'test',
duration: 60,
_id,
date: new Date().toDateString()
};
const addRes = await fetch(url + `/api/users/${_id}/exercises`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `description=${expected.description}&duration=${expected.duration}`
});
if (addRes.ok) {
const logRes = await fetch(url + `/api/users/${_id}/logs`);
if (logRes.ok) {
const { count } = await logRes.json();
assert(count);
} else {
throw new Error(`${logRes.status} ${logRes.statusText}`);
}
} else {
throw new Error(`${addRes.status} ${addRes.statusText}`);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
È possibile aggiungere parametri `from`, `to` e`limit` alla richiesta `/api/users/:_id/logs` per ricevere parte del log di ogni utente. `from` e `to` sono date nel formato `yyyy-mm-dd`. `limit` è un numero intero che indica quanti log devono essere restituiti.
```js
async (getUserInput) => {
const url = getUserInput('url');
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
const expected = {
username,
description: 'test',
duration: 60,
_id,
date: new Date().toDateString()
};
const addExerciseRes = await fetch(url + `/api/users/${_id}/exercises`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `description=${expected.description}&duration=${expected.duration}&date=1990-01-01`
});
const addExerciseTwoRes = await fetch(url + `/api/users/${_id}/exercises`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `description=${expected.description}&duration=${expected.duration}&date=1990-01-02`
});
if (addExerciseRes.ok && addExerciseTwoRes.ok) {
const logRes = await fetch(
url + `/api/users/${_id}/logs?from=1989-12-31&to=1990-01-03`
);
if (logRes.ok) {
const { log } = await logRes.json();
assert.isArray(log);
assert.equal(2, log.length);
} else {
throw new Error(`${logRes.status} ${logRes.statusText}`);
}
const limitRes = await fetch(
url + `/api/users/${_id}/logs?limit=1`
);
if (limitRes.ok) {
const { log } = await limitRes.json();
assert.isArray(log);
assert.equal(1, log.length);
} else {
throw new Error(`${limitRes.status} ${limitRes.statusText}`);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,88 @@
---
id: bd7158d8c443edefaeb5bd0f
title: Microservizio Metadati di un file
challengeType: 4
forumTopicId: 301506
dashedName: file-metadata-microservice
---
# --description--
Costruisci un'app JavaScript full-stack che sia funzionalmente simile a questa: <https://file-metadata-microservice.freecodecamp.rocks/>. Lavorare su questo progetto ti porterà a scrivere il tuo codice utilizzando uno dei seguenti metodi:
- Clonare [questa repository GitHub](https://github.com/freeCodeCamp/boilerplate-project-filemetadata/) e completare il tuo progetto localmente.
- Usare [la nostra bozza di progetto su Replit](https://replit.com/github/freeCodeCamp/boilerplate-project-filemetadata) per completare il tuo progetto.
- Usare un costruttore di siti di tua scelta per completare il progetto. Assicurati di incorporare tutti i file della nostra repository GitHub.
Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata da qualche parte di pubblico. Quindi invia l'URL nel campo `Solution Link`. Facoltativamente, invia anche un link al codice sorgente dei tuoi progetti nel campo `GitHub Link`.
# --instructions--
**SUGGERIMENTO:** Puoi usare il pacchetto npm `multer` per gestire il caricamento dei file.
# --hints--
È necessario fornire il proprio progetto, non l'URL di esempio.
```js
(getUserInput) => {
assert(
!/.*\/file-metadata-microservice\.freecodecamp\.rocks/.test(
getUserInput('url')
)
);
};
```
Puoi inviare un modulo che include un caricamento di file.
```js
async (getUserInput) => {
const site = await fetch(getUserInput('url'));
const data = await site.text();
const doc = new DOMParser().parseFromString(data, 'text/html');
assert(doc.querySelector('input[type="file"]'));
};
```
Il campo di input del file form ha l'attributo `name` impostato su `upfile`.
```js
async (getUserInput) => {
const site = await fetch(getUserInput('url'));
const data = await site.text();
const doc = new DOMParser().parseFromString(data, 'text/html');
assert(doc.querySelector('input[name="upfile"]'));
};
```
Inviando un file, riceverai il `name`, il `type` e la dimensione (`size`) in byte del file, all'interno della risposta JSON.
```js
async (getUserInput) => {
const formData = new FormData();
const fileData = await fetch(
'https://cdn.freecodecamp.org/weather-icons/01d.png'
);
const file = await fileData.blob();
formData.append('upfile', file, 'icon');
const data = await fetch(getUserInput('url') + '/api/fileanalyse', {
method: 'POST',
body: formData
});
const parsed = await data.json();
assert.property(parsed, 'size');
assert.equal(parsed.name, 'icon');
assert.equal(parsed.type, 'image/png');
};
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,77 @@
---
id: bd7158d8c443edefaeb5bdff
title: Microservizio Parser di header della richiesta
challengeType: 4
forumTopicId: 301507
dashedName: request-header-parser-microservice
---
# --description--
Costruisci un'app JavaScript full-stack che sia funzionalmente simile a questa: <https://request-header-parser-microservice.freecodecamp.rocks/>. Lavorare su questo progetto ti porterà a scrivere il tuo codice utilizzando uno dei seguenti metodi:
- Clonare [questa repository GitHub](https://github.com/freeCodeCamp/boilerplate-project-headerparser/) e completare il tuo progetto localmente.
- Usare [la nostra bozza di progetto su Replit](https://replit.com/github/freeCodeCamp/boilerplate-project-headerparser) per completare il tuo progetto.
- Usare un costruttore di siti di tua scelta per completare il progetto. Assicurati di incorporare tutti i file della nostra repository GitHub.
Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata da qualche parte di pubblico. Quindi invia l'URL nel campo `Solution Link`. Facoltativamente, invia anche un link al codice sorgente del tuo progetto nel campo `GitHub Link`.
# --hints--
È necessario fornire il proprio progetto, non l'URL di esempio.
```js
(getUserInput) => {
assert(
!/.*\/request-header-parser-microservice\.freecodecamp\.rocks/.test(
getUserInput('url')
)
);
};
```
Una richiesta a `/api/whoami` dovrebbe restituire un oggetto JSON con il tuo indirizzo IP nella chiave `ipaddress`.
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api/whoami').then(
(data) => assert(data.ipaddress && data.ipaddress.length > 0),
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Una richiesta a `/api/whoami` dovrebbe restituire un oggetto JSON con la tua lingua preferita nella chiave `language`.
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api/whoami').then(
(data) => assert(data.language && data.language.length > 0),
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Una richiesta a `/api/whoami` dovrebbe restituire un oggetto JSON con il tuo software nella chiave `software`.
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api/whoami').then(
(data) => assert(data.software && data.software.length > 0),
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,154 @@
---
id: bd7158d8c443edefaeb5bdef
title: Microservizio Timestamp
challengeType: 4
forumTopicId: 301508
dashedName: timestamp-microservice
---
# --description--
Costruisci un'app JavaScript full-stack che sia funzionalmente simile a questa: <https://timestamp-microservice.freecodecamp.rocks/>. Lavorare su questo progetto ti porterà a scrivere il tuo codice utilizzando uno dei seguenti metodi:
- Clonare [questa repository GitHub](https://github.com/freeCodeCamp/boilerplate-project-timestamp/) e completare il tuo progetto localmente.
- Usare [la nostra bozza di progetto su Replit](https://replit.com/github/freeCodeCamp/boilerplate-project-timestamp) per completare il tuo progetto.
- Usare un costruttore di siti di tua scelta per completare il progetto. Assicurati di incorporare tutti i file della nostra repository GitHub.
Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata da qualche parte di pubblico. Quindi invia l'URL nel campo `Solution Link`. Facoltativamente, invia anche un link al codice sorgente dei tuoi progetti nel campo `GitHub Link`.
# --hints--
È necessario fornire il proprio progetto, non l'URL di esempio.
```js
(getUserInput) => {
assert(
!/.*\/timestamp-microservice\.freecodecamp\.rocks/.test(getUserInput('url'))
);
};
```
Una richiesta a `/api/:date?` con una data valida dovrebbe restituire un oggetto JSON con una chiave `unix` che è un timestamp Unix della data di input in millisecondi
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api/2016-12-25').then(
(data) => {
assert.equal(
data.unix,
1482624000000,
'Should be a valid unix timestamp'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Una richiesta a `/api/:date?` con una data valida dovrebbe restituire un oggetto JSON con una chiave `utc` che è una stringa della data di immissione nel formato: `Thu, 01 Jan 1970 00:00:00 GMT`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api/2016-12-25').then(
(data) => {
assert.equal(
data.utc,
'Sun, 25 Dec 2016 00:00:00 GMT',
'Should be a valid UTC date string'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Una richiesta a `/api/1451001600000` dovrebbe restituire `{ unix: 1451001600000, utc: "Fri, 25 Dec 2015 00:00:00 GMT" }`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api/1451001600000').then(
(data) => {
assert(
data.unix === 1451001600000 &&
data.utc === 'Fri, 25 Dec 2015 00:00:00 GMT'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Il tuo progetto può gestire date che possono essere lette con successo da `new Date(date_string)`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api/05 October 2011').then(
(data) => {
assert(
data.unix === 1317772800000 &&
data.utc === 'Wed, 05 Oct 2011 00:00:00 GMT'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Se la stringa della data di input non è valida, l'api restituisce un oggetto con la struttura `{ error : "Invalid Date" }`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api/this-is-not-a-date').then(
(data) => {
assert.equal(data.error.toLowerCase(), 'invalid date');
},
(xhr) => {
assert(xhr.responseJSON.error.toLowerCase() === 'invalid date');
}
);
```
Un parametro data vuoto dovrebbe restituire l'ora corrente in un oggetto JSON con una chiave `unix`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api').then(
(data) => {
var now = Date.now();
assert.approximately(data.unix, now, 20000);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Un parametro data vuoto dovrebbe restituire l'ora corrente in un oggetto JSON con una chiave `utc`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/api').then(
(data) => {
var now = Date.now();
var serverTime = new Date(data.utc).getTime();
assert.approximately(serverTime, now, 20000);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,119 @@
---
id: bd7158d8c443edefaeb5bd0e
title: Microservizio di Abbreviazione URL
challengeType: 4
forumTopicId: 301509
dashedName: url-shortener-microservice
---
# --description--
Costruisci un'app JavaScript full-stack che sia funzionalmente simile a questa: <https://url-shortener-microservice.freecodecamp.rocks/>. Lavorare su questo progetto ti porterà a scrivere il tuo codice utilizzando uno dei seguenti metodi:
- Clonare [questa repository GitHub](https://github.com/freeCodeCamp/boilerplate-project-urlshortener/) e completare il tuo progetto localmente.
- Usare [la nostra bozza di progetto su Replit](https://replit.com/github/freeCodeCamp/boilerplate-project-urlshortener) per completare il tuo progetto.
- Usare un costruttore di siti di tua scelta per completare il progetto. Assicurati di incorporare tutti i file della nostra repository GitHub.
Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata da qualche parte di pubblico. Quindi invia l'URL nel campo `Solution Link`. Facoltativamente, invia anche un link al codice sorgente dei tuoi progetti nel campo `GitHub Link`.
# --instructions--
**SUGGERIMENTO:** Non dimenticare di utilizzare un middleware di analisi del body per gestire le richieste POST. Inoltre, potrai utilizzare la funzione `dns.lookup(host, cb)` dal modulo core `dns` per verificare un URL inviato.
# --hints--
È necessario fornire il proprio progetto, non l'URL di esempio.
```js
(getUserInput) => {
assert(
!/.*\/url-shortener-microservice\.freecodecamp\.rocks/.test(
getUserInput('url')
)
);
};
```
Puoi inviare via POST un URL a `/api/shorturl` e ottenere una risposta JSON con le proprietà `original_url` e `short_url`. Ecco un esempio: `{ original_url : 'https://freeCodeCamp.org', short_url : 1}`
```js
async (getUserInput) => {
const url = getUserInput('url');
const urlVariable = Date.now();
const fullUrl = `${url}/?v=${urlVariable}`
const res = await fetch(url + '/api/shorturl', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `url=${fullUrl}`
});
if (res.ok) {
const { short_url, original_url } = await res.json();
assert.isNotNull(short_url);
assert.strictEqual(original_url, `${url}/?v=${urlVariable}`);
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
Quando visiti `/api/shorturl/<short_url>`, verrai reindirizzato all'URL originale.
```js
async (getUserInput) => {
const url = getUserInput('url');
const urlVariable = Date.now();
const fullUrl = `${url}/?v=${urlVariable}`
let shortenedUrlVariable;
const postResponse = await fetch(url + '/api/shorturl', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `url=${fullUrl}`
});
if (postResponse.ok) {
const { short_url } = await postResponse.json();
shortenedUrlVariable = short_url;
} else {
throw new Error(`${postResponse.status} ${postResponse.statusText}`);
}
const getResponse = await fetch(
url + '/api/shorturl/' + shortenedUrlVariable
);
if (getResponse) {
const { redirected, url } = getResponse;
assert.isTrue(redirected);
assert.strictEqual(url,fullUrl);
} else {
throw new Error(`${getResponse.status} ${getResponse.statusText}`);
}
};
```
Se passi un URL non valido che non segue il formato valido `http://www.example.com`, la risposta JSON conterrà `{ error: 'invalid url' }`
```js
async (getUserInput) => {
const url = getUserInput('url');
const res = await fetch(url + '/api/shorturl', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `url=ftp:/john-doe.org`
});
if (res.ok) {
const { error } = await res.json();
assert.isNotNull(error);
assert.strictEqual(error.toLowerCase(), 'invalid url');
} else {
throw new Error(`${res.status} ${res.statusText}`);
}
};
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,79 @@
---
id: 587d7fb1367417b2b2512bf4
title: Concatenare il middleware per creare un Time Server
challengeType: 2
forumTopicId: 301510
dashedName: chain-middleware-to-create-a-time-server
---
# --description--
Il middleware può essere montato su un percorso specifico utilizzando `app.METHOD(path, middlewareFunction)`. Il middleware può anche essere concatenato all'interno della definizione del percorso.
Guarda l'esempio seguente:
```js
app.get('/user', function(req, res, next) {
req.user = getTheUserSync(); // Hypothetical synchronous operation
next();
}, function(req, res) {
res.send(req.user);
});
```
Questo approccio è utile per dividere le operazioni server in unità più piccole. Questo porta a una migliore struttura delle app, e alla possibilità di riutilizzare il codice in luoghi diversi. Questo approccio può essere utilizzato anche per eseguire una qualche convalida sui dati. In ogni punto dello stack middleware è possibile bloccare l'esecuzione della catena corrente e passare il controllo a funzioni specificamente progettate per gestire gli errori. Oppure è possibile passare il controllo alla prossima rotta corrispondente, per gestire casi speciali. Vedremo come nella sezione Express avanzata.
# --instructions--
Nel percorso `app.get('/now', ...)` concatena una funzione middleware e il gestore finale. Nella funzione middleware dovresti aggiungere l'ora corrente all'oggetto della richiesta nella chiave `req.time`. Puoi utilizzare `new Date().toString()`. Nel gestore, rispondi con un oggetto JSON, utilizzando la struttura `{time: req.time}`.
**Nota:** Il test non sarà superato se non concatenerai il middleware. Se monti la funzione altrove, il test fallirà, anche se il risultato dell'uscita sarà corretto.
# --hints--
L'endpoint /now dovrebbe avere il middleware montato
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/chain-middleware-time').then(
(data) => {
assert.equal(
data.stackLength,
2,
'"/now" route has no mounted middleware'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
L'endpoint /now dovrebbe restituire un tempo che è di +/- 20 secondi da ora
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/chain-middleware-time').then(
(data) => {
var now = new Date();
assert.isAtMost(
Math.abs(new Date(data.time) - now),
20000,
'the returned time is not between +- 20 secs from now'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,78 @@
---
id: 587d7fb2367417b2b2512bf8
title: Ottenere dati dalle richieste POST
challengeType: 2
forumTopicId: 301511
dashedName: get-data-from-post-requests
---
# --description--
Monta un gestore POST sul percorso `/name`. È lo stesso percorso di prima. Abbiamo preparato un modulo nella pagina html principale. Invierà gli stessi dati dell'esercizio 10 (stringa di ricerca). Se il body parser è configurato correttamente, dovresti trovare i parametri nell'oggetto `req.body`. Dai un'occhiata al solito esempio della biblioteca:
<blockquote>route: POST '/library'<br>urlencoded_body: userId=546&#x26;bookId=6754 <br>req.body: {userId: '546', bookId: '6754'}</blockquote>
Rispondi con lo stesso oggetto JSON di prima: `{name: 'firstname lastname'}`. Verifica se il tuo endpoint funziona utilizzando il modulo html che abbiamo fornito nella pagina principale dell'app.
Suggerimento: ci sono diversi altri metodi http diversi da GET e POST. E per convenzione c'è una corrispondenza tra il verbo http, e l'operazione che si sta per eseguire sul server. La mappatura convenzionale è:
POST (talvolta PUT) - Crea una nuova risorsa utilizzando le informazioni inviate con la richiesta,
GET - Leggi una risorsa esistente senza modificarla,
PUT o PATCH (a volte POST) - Aggiorna una risorsa utilizzando i dati inviati,
DELETE => Elimina una risorsa.
Ci sono anche un paio di altri metodi che vengono utilizzati per negoziare una connessione con il server. Tranne che da GET, tutti gli altri metodi sopra elencati possono avere un carico utile (cioè i dati nel corpo della richiesta). Il middleware body-parser funziona anche con questi metodi.
# --hints--
Test 1: Il tuo endpoint API dovrebbe rispondere con il nome corretto
```js
(getUserInput) =>
$.post(getUserInput('url') + '/name', { first: 'Mick', last: 'Jagger' }).then(
(data) => {
assert.equal(
data.name,
'Mick Jagger',
'Test 1: "POST /name" route does not behave as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Test 2: Il tuo endpoint API dovrebbe rispondere con il nome corretto
```js
(getUserInput) =>
$.post(getUserInput('url') + '/name', {
first: 'Keith',
last: 'Richards'
}).then(
(data) => {
assert.equal(
data.name,
'Keith Richards',
'Test 2: "POST /name" route does not behave as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,67 @@
---
id: 587d7fb2367417b2b2512bf6
title: Ottenere l'input del parametro query dal client
challengeType: 2
forumTopicId: 301512
dashedName: get-query-parameter-input-from-the-client
---
# --description--
Un altro modo comune per ottenere input dal client è codificare i dati dopo il percorso della rotta, utilizzando una stringa di interrogazione (query). La stringa di query è delimitata da un punto interrogativo (?), e include le coppie campo=valore. Ogni coppia è separata da un simbolo &. Express può analizzare i dati dalla stringa di query e popolare l'oggetto `req.query`. Alcuni caratteri, come la percentuale (%), non possono essere presenti negli URL e devono essere codificati in un formato diverso prima di poterli inviare. Se accedi all'API da JavaScript, puoi usare metodi specifici per codificare/decodificare questi caratteri.
<blockquote>route_path: '/library'<br>actual_request_URL: '/library?userId=546&#x26;bookId=6754' <br>req.query: {userId: '546', bookId: '6754'}</blockquote>
# --instructions--
Costruisci un endpoint API, montato su `GET /name`. Rispondi con un documento JSON, usando la struttura `{ name: 'firstname lastname'}`. I parametri del nome e del cognome devono essere codificati in una stringa di query, ad esempio `?first=firstname&last=lastname`.
**Nota:** Nel seguente esercizio riceverai i dati da una richiesta POST, allo stesso percorso `/name`. Se vuoi, puoi usare il metodo `app.route(path).get(handler).post(handler)`. Questa sintassi consente di concatenare diversi gestori di verbi sullo stesso percorso. Puoi risparmiare un po' di digitazione, e avere un codice più pulito.
# --hints--
Test 1: Il tuo endpoint API dovrebbe rispondere con il nome corretto
```js
(getUserInput) =>
$.get(getUserInput('url') + '/name?first=Mick&last=Jagger').then(
(data) => {
assert.equal(
data.name,
'Mick Jagger',
'Test 1: "GET /name" route does not behave as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Test 2: Il tuo endpoint API dovrebbe rispondere con il nome corretto
```js
(getUserInput) =>
$.get(getUserInput('url') + '/name?last=Richards&first=Keith').then(
(data) => {
assert.equal(
data.name,
'Keith Richards',
'Test 2: "GET /name" route does not behave as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,65 @@
---
id: 587d7fb2367417b2b2512bf5
title: Ottenere l'input del parametro della rotta dal client
challengeType: 2
forumTopicId: 301513
dashedName: get-route-parameter-input-from-the-client
---
# --description--
Quando costruiamo un'API, dobbiamo consentire agli utenti di comunicarci cosa vogliono ottenere dal nostro servizio. Ad esempio, se il client richiede informazioni su un utente memorizzato nel database, hanno bisogno di un modo per farci sapere a quale utente sono interessati. Un modo possibile per raggiungere questo risultato è utilizzare i parametri della rotta. I parametri della rotta sono denominati segmenti dell'URL, e sono delimitati da slash (/). Ogni segmento cattura il valore della parte dell'URL che corrisponde alla sua posizione. I valori acquisiti possono essere trovati nell'oggetto `req.params`.
<blockquote>route_path: '/user/:userId/book/:bookId'<br>actual_request_URL: '/user/546/book/6754' <br>req.params: {userId: '546', bookId: '6754'}</blockquote>
# --instructions--
Costruisci un server echo, montato sul percorso `GET /:word/echo`. Rispondi con un oggetto JSON, usando la struttura `{echo: word}`. Puoi trovare la parola da ripetere in `req.params.word`. Puoi testare il percorso dalla barra degli indirizzi del tuo browser, visitando alcuni percorsi corrispondenti, ad esempio `your-app-rootpath/freecodecamp/echo`.
# --hints--
Test 1: il tuo server echo dovrebbe ripetere correttamente le parole
```js
(getUserInput) =>
$.get(getUserInput('url') + '/eChOtEsT/echo').then(
(data) => {
assert.equal(
data.echo,
'eChOtEsT',
'Test 1: the echo server is not working as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Test 2: il tuo server echo dovrebbe ripetere correttamente le parole
```js
(getUserInput) =>
$.get(getUserInput('url') + '/ech0-t3st/echo').then(
(data) => {
assert.equal(
data.echo,
'ech0-t3st',
'Test 2: the echo server is not working as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,57 @@
---
id: 587d7fb1367417b2b2512bf3
title: Implementare un middleware logger di richiesta a livello radice
challengeType: 2
forumTopicId: 301514
dashedName: implement-a-root-level-request-logger-middleware
---
# --description--
In precedenza, sei stato introdotto alla funzione middleware `express.static()`. Ora è il momento di vedere cosa è un middleware in modo più dettagliato. Le funzioni middleware sono funzioni che richiedono 3 argomenti: l'oggetto richiesta (request), l'oggetto risposta (response) e la funzione successiva (next) nel ciclo richiesta-risposta dell'applicazione. Queste funzioni eseguono del codice che può avere effetti collaterali sull'app, e di solito aggiungono informazioni alla richiesta o agli oggetti di risposta. Possono anche terminare il ciclo inviando una risposta quando è soddisfatta una certa condizione. Se non inviano la risposta quando hanno finito, iniziano l'esecuzione della funzione successiva nello stack. Questo innesca la chiamata del terzo argomento, `next()`.
Considera l'esempio seguente:
```js
function(req, res, next) {
console.log("I'm a middleware...");
next();
}
```
Supponiamo che tu abbia montato questa funzione su una rotta. Quando una richiesta corrisponde alla rotta, mostrerà la stringa “Im a middleware…”, dopodiché eseguirà la funzione successiva nello stack. In questo esercizio, costruirai un middleware a livello di radice. Come hai visto nella sfida 4, per montare una funzione middleware a livello di radice, puoi usare il metodo `app.use(<mware-function>)`. In questo caso, la funzione verrà eseguita per tutte le richieste, ma è anche possibile impostare condizioni più specifiche. Ad esempio, se desideri che una funzione venga eseguita solo per le richieste POST, puoi utilizzare `app.post(<mware-function>)`. Esistono metodi analoghi per tutti i verbi HTTP (GET, DELETE, PUT, …).
# --instructions--
Costruisci un semplice logger. Per ogni richiesta, esso dovrebbe scrivere nella console una stringa con il seguente formato: `method path - ip`. L'output dovrebbe assomigliare a questo: `GET /json - ::ffff:127.0.0.1`. Nota che c'è uno spazio tra `method` e `path` e che il trattino che separa `path` e `ip` è circondato da uno spazio su entrambi i lati. Puoi ottenere il metodo di richiesta (il verbo http), il percorso relativo e l'ip del chiamante dall'oggetto request utilizzando `req.method`, `req.path` e `req.ip`. Ricordati di chiamare `next()` quando hai finito, o il tuo server rimarrà bloccato per sempre. Assicurati di avere il 'Logs' aperto, e guarda cosa succede quando arriva qualche richiesta.
**Nota:** Express valuta le funzioni nell'ordine in cui appaiono nel codice. Questo vale anche per i middleware. Se vuoi che funzioni per tutte le rotte, dovresti montarlo prima di loro.
# --hints--
Il middleware del logger di livello radice dovrebbe essere attivo
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/root-middleware-logger').then(
(data) => {
assert.isTrue(
data.passed,
'root-level logger is not working as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,53 @@
---
id: 587d7fb0367417b2b2512bed
title: Introduzione alla console di Node
challengeType: 2
forumTopicId: 301515
dashedName: meet-the-node-console
---
# --description--
Lavorare su queste sfide ti porterà a scrivere il tuo codice utilizzando uno dei seguenti metodi:
- Clonare [questo repository GitHub](https://github.com/freeCodeCamp/boilerplate-express/) e completare queste sfide localmente.
- Usare [la nostra bozza di progetto su Replit](https://replit.com/github/freeCodeCamp/boilerplate-express) per completare queste sfide.
- Usa un costruttore di siti di tua scelta per completare il progetto. Assicurati di incorporare tutti i file della nostra repository GitHub.
Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata da qualche parte di pubblico. Quindi invia l'URL nel campo `Solution Link`.
Durante il processo di sviluppo, è importante essere in grado di controllare cosa sta succedendo nel tuo codice.
Node è solo un ambiente JavaScript. Come per il JavaScript lato client, puoi usare la console per visualizzare utili informazioni di debug. Sulla tua macchina locale, vedrai l'output della console in un terminale. Su Replit, un terminale è aperto nel riquadro destro per impostazione predefinita.
Ti consigliamo di mantenere il terminale aperto mentre lavori a a queste sfide. Leggendo l'output nel terminale, potrai vedere eventuali errori.
# --instructions--
Modifica il file `myApp.js` per scrivere "Hello World" nella console.
# --hints--
`"Hello World"` dovrebbe essere visualizzato nella console
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/hello-console').then(
(data) => {
assert.isTrue(data.passed, '"Hello World" is not in the server console');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,51 @@
---
id: 587d7fb0367417b2b2512bef
title: Servire un file HTML
challengeType: 2
forumTopicId: 301516
dashedName: serve-an-html-file
---
# --description--
È possibile rispondere alle richieste con un file utilizzando il metodo `res.sendFile(path)`. Puoi inserirlo all'interno del gestore della rotta `app.get('/', ...)`. Dietro le quinte, questo metodo imposterà le intestazioni appropriate per istruire il browser su come gestire il file che si desidera inviare, in base al suo tipo. Quindi leggerà e invierà il file. Questo metodo necessita di un percorso di file assoluto. Ti consigliamo di utilizzare la variabile globale Node `__dirname` per calcolare il percorso in questo modo:
```js
absolutePath = __dirname + relativePath/file.ext
```
# --instructions--
Invia il file `/views/index.html` come risposta alle richieste GET al percorso `/`. Guardando la tua app live, dovresti vedere una grossa intestazione HTML (e un modulo, che useremo successivamente...) senza alcuno stile applicato.
**Nota:** Puoi modificare la soluzione della sfida precedente o crearne una nuova. Se crei una nuova soluzione, tieni presente che Express valuta i percorsi dall'alto verso il basso ed esegue il gestore alla prima corrispondenza. Dovrai commentare la soluzione precedente, o il server continuerà a rispondere con una stringa.
# --hints--
La tua app dovrebbe servire il file views/index.html
```js
(getUserInput) =>
$.get(getUserInput('url')).then(
(data) => {
assert.match(
data,
/<h1>.*<\/h1>/,
'Your app does not serve the expected HTML'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,47 @@
---
id: 587d7fb1367417b2b2512bf1
title: Servire un JSON su una rotta specifica
challengeType: 2
forumTopicId: 301517
dashedName: serve-json-on-a-specific-route
---
# --description--
Mentre un server HTML serve HTML, un'API serve dati. Un'API <dfn>REST</dfn> (REpresentational State Transfer) consente lo scambio di dati in modo semplice, senza la necessità per i client di conoscere alcun dettaglio sul server. Il client deve solo sapere dove è la risorsa (l'URL), e l'azione che vuole eseguire su di essa (il verbo). Il verbo GET viene utilizzato quando stai recuperando alcune informazioni, senza modificare nulla. Al giorno d'oggi, il formato dati preferito per trasferire informazioni sul Web è JSON. In poche parole, JSON è un modo conveniente per rappresentare un oggetto JavaScript come una stringa, in modo che possa essere facilmente trasmesso.
Creiamo una semplice API creando una rotta (route) che risponda con JSON al percorso `/json`. Puoi farlo come al solito, con il metodo `app.get()`. All'interno del gestore della rotta, usa il metodo `res.json()`, passandogli un oggetto come argomento. Questo metodo chiude il ciclo richiesta-risposta, restituendo i dati. Dietro le quinte, converte un oggetto JavaScript valido in una stringa, poi imposta le intestazioni appropriate per dire al tuo browser che stai servendo JSON, e restituisce i dati. Un oggetto valido ha la solita struttura `{key: data}`. `data` può essere un numero, una stringa, un oggetto annidato o un array. `data` può anche essere una variabile o il risultato di una chiamata di funzione, nel qual caso sarà valutato prima di essere convertito in una stringa.
# --instructions--
Servi l'oggetto `{"message": "Hello json"}` come risposta, in formato JSON, alle richieste GET per il percorso `/json`. Quindi punta il tuo browser a `your-app-url/json`, dovresti vedere il messaggio sullo schermo.
# --hints--
L'endpoint `/json` dovrebbe servire l'oggetto json `{"message": "Hello json"}`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/json').then(
(data) => {
assert.equal(
data.message,
'Hello json',
"The '/json' endpoint does not serve the right data"
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,51 @@
---
id: 587d7fb0367417b2b2512bf0
title: Servire Risorse Statiche
challengeType: 2
forumTopicId: 301518
dashedName: serve-static-assets
---
# --description--
Un server HTML di solito ha una o più directory che sono accessibili all'utente. È possibile posizionare lì le risorse statiche necessarie per l'applicazione (fogli di stile, script, immagini).
In Express, puoi mettere in atto questa funzionalità usando il middleware `express.static(path)`, dove il parametro `path` è il percorso assoluto della cartella contenente le risorse.
Se non sai cosa è un middleware... non ti preoccupare, ne discuteremo in dettaglio più tardi. Fondamentalmente, i middleware sono funzioni che intercettano i gestori delle rotte, aggiungendo un certo tipo di informazioni. Un middleware deve essere montato usando il metodo `app.use(path, middlewareFunction)`. Il primo argomento `path` è facoltativo. Se non viene passato, il middleware verrà eseguito per tutte le richieste.
# --instructions--
Monta il middleware `express.static()` sul percorso `/public` con `app.use()`. Il percorso assoluto della cartella asset è `__dirname + /public`.
Ora la tua app dovrebbe essere in grado di servire un foglio di stile CSS. Nota che il file `/public/style.css` è referenziato nel `/views/index.html` nel codice standard. Adesso la tua pagina principale dovrebbe avere un aspetto un po' migliore!
# --hints--
La tua app dovrebbe servire i file di risorsa dalla directory `/public` al percorso `/public`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/public/style.css').then(
(data) => {
assert.match(
data,
/body\s*\{[^\}]*\}/,
'Your app does not serve static assets'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,57 @@
---
id: 587d7fb0367417b2b2512bee
title: Avviare un server Express funzionante
challengeType: 2
forumTopicId: 301519
dashedName: start-a-working-express-server
---
# --description--
Nelle prime due righe del file `myApp.js` puoi vedere quanto sia facile creare un oggetto app Express. Questo oggetto ha diversi metodi, che conoscerai in queste sfide. Un metodo fondamentale è `app.listen(port)`. Dice al tuo server di mettersi in ascolto su una data porta, mettendola in uno stato attivo. Per motivi di test, abbiamo bisogno che l'app sia in esecuzione in background per cui abbiamo aggiunto questo metodo nel file `server.js` per te.
Serviamo la nostra prima stringa! In Express, le rotte hanno la seguente struttura: `app.METHOD(PATH, HANDLER)`. METHOD è un metodo http in minuscolo. PATH è un percorso relativo sul server (può essere una stringa, o anche un'espressione regolare). HANDLER è una funzione che Express chiama quando la rotta corrisponde. I gestori assumono la forma `function(req, res) {...}`, dove req è l'oggetto request (richiesta), e res è l'oggetto response (risposta). Ad esempio, il gestore
```js
function(req, res) {
res.send('Response String');
}
```
servirà la stringa 'Response String'.
# --instructions--
Utilizza il metodo `app.get()` per servire la stringa "Hello Express" alle richieste GET corrispondenti al percorso `/` (root). Assicurati che il codice funzioni guardando i log, quindi guarda i risultati nell'anteprima se utilizzi Replit.
**Nota:** Tutto il codice per queste lezioni dovrebbe essere aggiunto tra le poche righe di codice di partenza.
# --hints--
La tua app dovrebbe servire la stringa 'Hello Express'
```js
(getUserInput) =>
$.get(getUserInput('url')).then(
(data) => {
assert.equal(
data,
'Hello Express',
'Your app does not serve the text "Hello Express"'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,63 @@
---
id: 587d7fb2367417b2b2512bf7
title: Usare il body parser per analizzare le richieste POST
challengeType: 2
forumTopicId: 301520
dashedName: use-body-parser-to-parse-post-requests
---
# --description--
Oltre a GET, c'è un altro verbo HTTP di uso comune, che è POST. POST è il metodo predefinito utilizzato per inviare dati dal client attraverso i moduli HTML. Nella convenzione REST, POST viene utilizzato per inviare dati che creeranno nuovi elementi nel database (un nuovo utente, o un nuovo post del blog). Non hai un database in questo progetto, ma imparerai comunque a gestire le richieste POST.
In questo tipo di richieste, i dati non appaiono nell'URL, sono nascosti nel corpo della richiesta. Il corpo fa parte della richiesta HTTP, chiamata anche payload (carico utile). Anche se i dati non sono visibili nell'URL, ciò non significa che siano privati. Per vedere perché, guarda il contenuto grezzo di una richiesta HTTP POST:
```http
POST /path/subpath HTTP/1.0
From: john@example.com
User-Agent: someBrowser/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
name=John+Doe&age=25
```
Come puoi vedere, il corpo è codificato come la query string. Questo è il formato predefinito usato dai moduli HTML. Con Ajax, è anche possibile utilizzare JSON per gestire dati che hanno una struttura più complessa. C'è anche un altro tipo di codifica: multipart/form-data. Questo viene utilizzato per caricare file binari. In questo esercizio, utilizzerai un corpo urlencoded. Per analizzare i dati provenienti dalle richieste POST, dovrai installare il pacchetto `body-parser`. Questo pacchetto consente di utilizzare una serie di middleware, che possono decodificare i dati in diversi formati.
# --instructions--
Installa il modulo `body-parser` nel tuo `package.json`. Poi, richiedilo con `require` all'inizio del file. Memorizzalo in una variabile chiamata `bodyParser`. Il middleware per gestire i dati urlencoded viene restituito da `bodyParser.urlencoded({extended: false})`. Passa ad `app.use()` la funzione restituita dal metodo invocato prima. Come al solito, il middleware deve essere montato prima di tutte le rotte che dipendono da esso.
**Nota:** `extended` è un'opzione di configurazione che dice al `body-parser` quale analisi deve essere utilizzata. Quando `extended=false` viene utilizzata la libreria di codifica classica `querystring`. Quando `extended=true` viene usata per il parsing la libreria `qs`.
Quando si utilizza `extended=false`, i valori possono essere solo stringhe o array. L'oggetto restituito quando si utilizza `querystring` non eredita prototipalmente da `Object`, predefinito in JavaScript, quindi funzioni come `hasOwnProperty` e `toString` non saranno disponibili. La versione estesa consente una maggiore flessibilità dei dati, ma è superata da JSON.
# --hints--
Il middleware 'body-parser' dovrebbe essere montato
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/add-body-parser').then(
(data) => {
assert.isAbove(
data.mountedAt,
0,
'"body-parser" is not mounted correctly'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,52 @@
---
id: 587d7fb1367417b2b2512bf2
title: Usare il file .env
challengeType: 2
forumTopicId: 301521
dashedName: use-the--env-file
---
# --description--
Il file `.env` è un file nascosto che viene utilizzato per passare le variabili d'ambiente alla tua applicazione. Questo file è segreto, nessuno tranne te può accedervi, e può essere utilizzato per memorizzare i dati che desideri mantenere privati o nascosti. Ad esempio, puoi memorizzare le chiavi API di servizi esterni o l'URI del database. Puoi anche usarlo per memorizzare le opzioni di configurazione. Impostando le opzioni di configurazione, puoi modificare il comportamento della tua applicazione, senza la necessità di riscrivere una parte di codice.
Le variabili di ambiente sono accessibili dall'app come `process.env.VAR_NAME`. L'oggetto `process.env` è un oggetto Node globale e le variabili sono passate come stringhe. Per convenzione, i nomi delle variabili sono tutti in maiuscolo, con parole separate da un trattino basso. `.env` è un file di shell, quindi non è necessario racchiudere i nomi o i valori tra virgolette. È anche importante notare che non ci possono essere degli spazi intorno al segno uguale quando si assegnano valori alle variabili, ad esempio `VAR_NAME=value`. Normalmente metterai ogni definizione di variabile in una riga separata.
# --instructions--
Aggiungiamo una variabile d'ambiente come opzione di configurazione.
Crea un file `.env` nella directory principale del tuo progetto e memorizza la variabile `MESSAGE_STYLE=uppercase` in esso.
Poi, nel gestore della rotta GET `/json` che hai creato nell'ultima sfida, trasforma il messaggio dell'oggetto di risposta in maiuscolo se `process.env.MESSAGE_STYLE` è uguale a `uppercase`. L'oggetto della risposta dovrebbe essere `{"message": "Hello json"}` o `{"message": "HELLO JSON"}`, a seconda del valore di `MESSAGE_STYLE`.
**Nota:** Se stai usando Replit, non puoi creare un file `.env`. Utilizza invece la scheda <dfn>SECRETS</dfn> integrata per aggiungere la variabile.
# --hints--
La risposta dell'endpoint `/json` dovrebbe cambiare in base alla variabile d'ambiente `MESSAGE_STYLE`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/use-env-vars').then(
(data) => {
assert.isTrue(
data.passed,
'The response of "/json" does not change according to MESSAGE_STYLE'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,52 @@
---
id: 587d7fb3367417b2b2512bfc
title: Aggiungere una descrizione al tuo package.json
challengeType: 2
forumTopicId: 301522
dashedName: add-a-description-to-your-package-json
---
# --description--
La parte successiva di un buon file package.json è il campo `description`, che conterrà una breve ma informativa descrizione del progetto.
Se un giorno avessi intenzione di pubblicare un pacchetto su npm, questa è la stringa che dovrebbe vendere la tua idea all'utente quando decide se installare o meno il pacchetto. Tuttavia, questo non è l'unico caso di utilizzo per la descrizione: essa è un ottimo modo per riassumere ciò che un progetto fa. È altrettanto importante in qualsiasi progetto Node.js per aiutare altri sviluppatori, futuri manutentori o anche il futuro te stesso a comprendere il progetto velocemente.
Indipendentemente da ciò che prevedi per il vostro progetto, una descrizione è sicuramente consigliata. Ecco un esempio:
```json
"description": "A project that does something awesome",
```
# --instructions--
Aggiungi una `description` al file package.json del tuo progetto.
**Nota:** Ricordati di usare le virgolette doppie (") per i nomi di campo e le virgole (,) per separare i campi.
# --hints--
package.json dovrebbe avere una chiave "description" valida
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert(packJson.description, '"description" is missing');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,48 @@
---
id: 587d7fb4367417b2b2512bfe
title: Aggiungere una licenza al tuo package.json
challengeType: 2
forumTopicId: 301523
dashedName: add-a-license-to-your-package-json
---
# --description--
Il campo `license` è dove informi gli utenti di quello che possono fare con il tuo progetto.
Alcune licenze comuni per progetti open source sono MIT e BSD. Le informazioni sulla licenza non sono richieste e le leggi sul copyright nella maggior parte dei paesi ti daranno la proprietà di ciò che crei senza che tu debba fare altro. Tuttavia, è sempre una buona pratica dichiarare esplicitamente quello che gli utenti possono e non possono fare. Ecco un esempio del campo di licenza:
```json
"license": "MIT",
```
# --instructions--
Compila il campo `license` nel file package.json del tuo progetto come ritieni opportuno.
# --hints--
package.json dovrebbe avere una chiave "license" valida
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert(packJson.license, '"license" is missing');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,46 @@
---
id: 587d7fb4367417b2b2512bff
title: Aggiungere una versione al tuo package.json
challengeType: 2
forumTopicId: 301525
dashedName: add-a-version-to-your-package-json
---
# --description--
`version` è uno dei campi obbligatori del file package.json. Questo campo descrive la versione corrente del tuo progetto. Ecco un esempio:
```json
"version": "1.2.0",
```
# --instructions--
Aggiungi una `version` al file package.json del tuo progetto.
# --hints--
package.json deve avere una chiave "version" valida
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert(packJson.version, '"version" is missing');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,84 @@
---
id: 587d7fb4367417b2b2512bfd
title: Aggiungere parole chiave al tuo package.json
challengeType: 2
forumTopicId: 301526
dashedName: add-keywords-to-your-package-json
---
# --description--
Il campo `keywords` è dove puoi descrivere il tuo progetto usando le parole chiave correlate. Ecco un esempio:
```json
"keywords": [ "descriptive", "related", "words" ],
```
Come puoi vedere, questo campo è strutturato come una serie di stringhe tra virgolette doppie.
# --instructions--
Aggiungi un array di stringhe adatte al campo `keywords` nel file package.json del tuo progetto.
Una delle parole chiave dovrebbe essere "freecodecamp".
# --hints--
package.json dovrebbe avere una chiave "keywords" valida
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert(packJson.keywords, '"keywords" is missing');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
il campo "keywords" dovrebbe essere un Array
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.isArray(packJson.keywords, '"keywords" is not an array');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
"keywords" dovrebbe includere "freecodecamp"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.include(
packJson.keywords,
'freecodecamp',
'"keywords" does not include "freecodecamp"'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,77 @@
---
id: 587d7fb4367417b2b2512c00
title: Espandere il tuo progetto con pacchetti esterni di npm
challengeType: 2
forumTopicId: 301527
dashedName: expand-your-project-with-external-packages-from-npm
---
# --description--
Uno dei più grandi motivi per utilizzare un gestore di pacchetti, è la loro potente gestione delle dipendenze. Invece di dover fare manualmente in modo di ottenere tutte le dipendenze ogni volta che si imposta un progetto su un nuovo computer, npm installa tutto per te automaticamente. Ma come può npm sapere esattamente di cosa ha bisogno il tuo progetto? Vai a vedere la sezione `dependencies` del tuo file package.json.
In questa sezione, i pacchetti richiesti dal progetto vengono memorizzati nel seguente formato:
```json
"dependencies": {
"package-name": "version",
"express": "4.14.0"
}
```
# --instructions--
Aggiungi la versione "2.14.0" del pacchetto "moment" al campo `dependencies` del tuo file package.json.
**Nota:** Moment è una comoda libreria per lavorare con l'ora e le date.
# --hints--
"dependencies" dovrebbe includere "moment"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
La versione di "moment" dovrebbe essere "2.14.0"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^[\^\~]?2\.14\.0/,
'Wrong version of "moment" installed. It should be 2.14.0'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,60 @@
---
id: 587d7fb3367417b2b2512bfb
title: 'Come utilizzare package.json, il nucleo di qualsiasi progetto Node.js o pacchetto npm'
challengeType: 2
forumTopicId: 301528
dashedName: how-to-use-package-json-the-core-of-any-node-js-project-or-npm-package
---
# --description--
Lavorare su queste sfide ti porterà a scrivere il tuo codice utilizzando uno dei seguenti metodi:
- Clonare [questo repository GitHub](https://github.com/freeCodeCamp/boilerplate-npm/) e completare queste sfide localmente.
- Usare [la nostra bozza di progetto su Replit](https://replit.com/github/freeCodeCamp/boilerplate-npm) per completare queste sfide.
- Usare un costruttore di siti a tua scelta per completare il progetto. Assicurati di incorporare tutti i file dal nostro repository GitHub.
Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata pubblicamente da qualche parte. Quindi invia l'URL nel campo `Solution Link`. Facoltativamente, invia anche un link al codice sorgente del tuo progetto nel campo `GitHub Link`.
Il file `package.json` è il centro di qualsiasi progetto Node.js o pacchetto npm. Memorizza informazioni sul tuo progetto, in modo simile a come la sezione &lt;head> di un documento HTML descrive il contenuto di una pagina web. Consiste di un singolo oggetto JSON dove le informazioni sono memorizzate in coppie chiave-valore. Ci sono solo due campi obbligatori; "name" e "version", ma è buona pratica fornire ulteriori informazioni sul tuo progetto che potrebbero essere utili per futuri utenti o manutentori.
Se guardi l'albero dei file del tuo progetto, troverai il file package.json al livello superiore dell'albero. Questo è il file che andremo a migliorare nelle prossime due sfide.
Una delle informazioni più comuni in questo file è il campo `author`. Specifica chi ha creato il progetto e può consistere in una stringa o un oggetto con informazioni di contatto o altri dettagli. Un oggetto è consigliato per progetti più grandi, ma una semplice stringa come l'esempio seguente farà al caso nostro per questo progetto.
```json
"author": "Jane Doe",
```
# --instructions--
Aggiungi il tuo nome come `author` del progetto nel file package.json.
**Nota:** Ricorda che stai scrivendo JSON, quindi tutti i nomi dei campi devono usare virgolette doppie (") ed essere separati con una virgola (,).
# --hints--
package.json deve avere una chiave "author" valida
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert(packJson.author, '"author" is missing');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,73 @@
---
id: 587d7fb5367417b2b2512c01
title: Gestire le dipendenze npm comprendendo il versioning semantico
challengeType: 2
forumTopicId: 301529
dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
---
# --description--
Il campo `versions` nella sezione delle dipendenze del tuo pacchetto npm segue quello che si chiama Versioning Semantico (SemVer), uno standard di settore per la versione del software al fine di rendere più facile la gestione delle dipendenze. Le librerie, i framework o altri strumenti pubblicati su npm dovrebbero utilizzare SemVer per comunicare chiaramente che tipo di cambiamenti i progetti possono aspettarsi se essi vengono aggiornati.
Conoscere SemVer può essere utile quando si sviluppa un software che utilizza dipendenze esterne (cosa che avviene quasi sempre). Un giorno, la tua comprensione di questi numeri ti salverà dall'introduzione accidentale di cambiamenti che potrebbero bloccare il tuo progetto senza capire perché le cose che hanno funzionato fino a ieri improvvisamente non funzionano più oggi. Questo è come il Semantic Versioning funziona secondo il sito ufficiale:
```json
"package": "MAJOR.MINOR.PATCH"
```
La versione MAJOR dovrebbe essere incrementata quando si effettuano modifiche API incompatibili. La versione MINOR dovrebbe essere incrementata quando si aggiungono funzionalità in modo retrocompatibile. La versione PATCH dovrebbe essere incrementata quando si fanno correzioni di bug retrocompatibili. Ciò significa che le PATCHes sono correzioni di bug e le MINOR aggiungono nuove funzionalità, ma nessuna delle due rischia di rompere quello che funzionava prima. Infine, le MAJORs aggiungono modifiche che non funzioneranno con le versioni precedenti.
# --instructions--
Nella sezione dependencies del tuo file package.json, cambia la `version` di moment per farlo corrispondere alla versione MAJOR 2, alla versione MINOR 10 e alla versione PATCH 2
# --hints--
"dependencies" dovrebbe includere "moment"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
La versione di "moment" dovrebbe essere "2.10.2"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.equal(
packJson.dependencies.moment,
'2.10.2',
'Wrong version of "moment". It should be 2.10.2'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,52 @@
---
id: 587d7fb5367417b2b2512c04
title: Rimuovere un pacchetto dalle tue dipendenze
challengeType: 2
forumTopicId: 301530
dashedName: remove-a-package-from-your-dependencies
---
# --description--
Ora hai testato alcuni modi per gestire le dipendenze del tuo progetto utilizzando la sezione delle dipendenze di package.json. Hai anche incluso dei pacchetti esterni aggiungendoli al file e hai detto a npm quali tipi di versioni desideri, utilizzando caratteri speciali come la tilde o il cursore.
Ma cosa dovresti fare per rimuovere un pacchetto esterno di cui non hai più bisogno? Potresti già averlo indovinato, basta rimuovere dalle dipendenze la coppia chiave-valore corrispondente a quel pacchetto.
Questo stesso metodo si applica anche alla rimozione di altri campi nel tuo package.json
# --instructions--
Rimuovi il pacchetto moment dalle tue dipendenze.
**Nota:** Assicurati di avere la giusta quantità di virgole dopo averlo rimosso.
# --hints--
"dependencies" non dovrebbe includere "moment"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.notProperty(
packJson.dependencies,
'moment',
'"dependencies" still includes "moment"'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,75 @@
---
id: 587d7fb5367417b2b2512c03
title: Usare il simbolo del cursore per specificare l'ultima versione minore di una dipendenza
challengeType: 2
forumTopicId: 301531
dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-dependency
---
# --description--
Simile a come la tilde che abbiamo imparato nell'ultima sfida permette a npm di installare l'ultima PATCH per una dipendenza, il cursore (caret, `^`) permette a npm di installare anche aggiornamenti futuri. La differenza è che il cursore permetterà sia gli aggiornamenti MINOR che le PATCHes.
La tua versione attuale di moment dovrebbe essere "~2.10.2" che permette a npm di installare l'ultima versione 2.10.x. Se invece dovessi usare il cursore (^) come prefisso di versione, npm avrebbe il permesso di aggiornare a qualsiasi versione 2.x.x.
```json
"package": "^1.3.8"
```
Questo permetterebbe di aggiornare qualsiasi versione 1.x.x del pacchetto.
# --instructions--
Usa il cursore (`^`) per prefissare la versione di moment nelle tue dipendenze e consentire a npm di aggiornarlo a qualsiasi nuova versione MINOR.
**Nota:** I numeri di versione non devono essere modificati.
# --hints--
"dependencies" dovrebbe includere "moment"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
La versione di "moment" dovrebbe corrispondere a "^2.x.x"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^\^2\./,
'Wrong version of "moment". It should be ^2.10.2'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,75 @@
---
id: 587d7fb5367417b2b2512c02
title: Usare il carattere tilde per utilizzare sempre l'ultima versione patch di una dipendenza
challengeType: 2
forumTopicId: 301532
dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-dependency
---
# --description--
Nell'ultima sfida, hai detto a npm di includere solo una versione specifica di un pacchetto. Questo è un modo utile per congelare le tue dipendenze, se hai bisogno di assicurarti che diverse parti del tuo progetto rimangano compatibili tra loro. Ma nella maggior parte dei casi d'uso, non vuoi perdere le correzioni di bug dal momento che spesso includono importanti patch di sicurezza e (si spera) non rompono le cose nel farlo.
Per consentire a una dipendenza npm di aggiornare all'ultima versione PATCH, è possibile prefissare la versione della dipendenza con il carattere tilde (`~`). Ecco un esempio di come consentire gli aggiornamenti di qualsiasi versione 1.3.x.
```json
"package": "~1.3.8"
```
# --instructions--
Nel file package.json, la tua regola corrente per come npm potrebbe aggiornare moment è usare una versione specifica (2.10.2). Ma ora desideriamo consentire l'ultima versione 2.10.x.
Usa il carattere tilde (`~`) per prefissare la versione di moment nelle tue dipendenze, e consentire a npm di aggiornarlo a qualsiasi nuova release PATCH.
**Nota:** I numeri di versione non devono essere modificati.
# --hints--
"dependencies" dovrebbe includere "moment"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
La versione di "moment" dovrebbe corrispondere a "~2.10.2"
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^\~2\.10\.2/,
'Wrong version of "moment". It should be ~2.10.2'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,76 @@
---
id: 587d7fb9367417b2b2512c12
title: Concatenare gli helper delle query per restringere i risultati di ricerca
challengeType: 2
forumTopicId: 301533
dashedName: chain-search-query-helpers-to-narrow-search-results
---
# --description--
Se non si passa la callback come ultimo argomento a `Model.find()` (o agli altri metodi di ricerca), la query non viene eseguita. È possibile memorizzare la query in una variabile per un uso successivo. Questo tipo di oggetto ti permette di costruire una query usando la sintassi di concatenazione. L'effettiva ricerca nel database viene eseguita quando alla fine concateni il metodo `.exec()`. Hai sempre bisogno di passare la tua callback a questo ultimo metodo. Ci sono molti helper di query: qui useremo i più comuni.
# --instructions--
Modifica la funzione `queryChain` per trovare persone a cui piace il cibo specificato dalla variabile denominata `foodToSearch`. Ordina per `name`, limita i risultati a due documenti e nascondi la loro età. Concatena `.find()`, `.sort()`, `.limit()`, `.select()`, e quindi `.exec()`. Passa la callback `done(err, data)` a `exec()`.
# --hints--
La concatenazione degli helper delle query dovrebbe avere successo
```js
(getUserInput) =>
$.ajax({
url: getUserInput('url') + '/_api/query-tools',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify([
{ name: 'Pablo', age: 26, favoriteFoods: ['burrito', 'hot-dog'] },
{ name: 'Bob', age: 23, favoriteFoods: ['pizza', 'nachos'] },
{ name: 'Ashley', age: 32, favoriteFoods: ['steak', 'burrito'] },
{ name: 'Mario', age: 51, favoriteFoods: ['burrito', 'prosciutto'] }
])
}).then(
(data) => {
assert.isArray(data, 'the response should be an Array');
assert.equal(
data.length,
2,
'the data array length is not what expected'
);
assert.notProperty(
data[0],
'age',
'The returned first item has too many properties'
);
assert.equal(
data[0].name,
'Ashley',
'The returned first item name is not what expected'
);
assert.notProperty(
data[1],
'age',
'The returned second item has too many properties'
);
assert.equal(
data[1].name,
'Mario',
'The returned second item name is not what expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,88 @@
---
id: 587d7fb6367417b2b2512c07
title: Creare un modello
challengeType: 2
forumTopicId: 301535
dashedName: create-a-model
---
# --description--
**C**RUD Parte I - CREATE
Innanzi tutto abbiamo bisogno di uno Schema. Ogni schema mappa a una collezione MongoDB. Definisce la forma dei documenti all'interno di quella collezione. Gli schemi sono elementi costitutivi dei modelli. Possono essere annidati per creare modelli complessi, ma per ora terremo le cose semplici. Un modello ti permette di creare istanze dei tuoi oggetti, chiamate documenti.
Replit è un vero server, e nei server reali le interazioni con il database avvengono nelle funzioni del gestore. Queste funzioni vengono eseguite quando si verifica qualche evento (ad esempio, qualcuno raggiunge un endpoint sulla tua API). Seguiremo lo stesso approccio in questi esercizi. La funzione `done()` è una callback che ci dice che possiamo procedere dopo aver completato un'operazione asincrona come l'inserimento, la ricerca, l'aggiornamento o la cancellazione. Segue la convenzione Node e dovrebbe essere chiamata come `done(null, data)` in caso di successo, o `done(err)` in caso di errore.
Attenzione - Quando interagisci con i servizi remoti, potrebbero verificarsi degli errori!
```js
/* Example */
const someFunc = function(done) {
//... do something (risky) ...
if (error) return done(error);
done(null, result);
};
```
# --instructions--
Crea uno schema persona chiamato `personSchema` con questo prototipo:
```markup
- Person Prototype -
--------------------
name : string [required]
age : number
favoriteFoods : array of strings (*)
```
Utilizzare i tipi di schema base di Mongoose. Se vuoi puoi anche aggiungere più campi, utilizzare semplici validatori come required o unique, e impostare dei valori predefiniti. Vedi i [Mongoose docs](http://mongoosejs.com/docs/guide.html).
Ora, crea un modello chiamato `Person` da `personSchema`.
# --hints--
Creare un'istanza da uno schema mongoose dovrebbe avere successo
```js
(getUserInput) =>
$.post(getUserInput('url') + '/_api/mongoose-model', {
name: 'Mike',
age: 28,
favoriteFoods: ['pizza', 'cheese']
}).then(
(data) => {
assert.equal(data.name, 'Mike', '"model.name" is not what expected');
assert.equal(data.age, '28', '"model.age" is not what expected');
assert.isArray(
data.favoriteFoods,
'"model.favoriteFoods" is not an Array'
);
assert.include(
data.favoriteFoods,
'pizza',
'"model.favoriteFoods" does not include the expected items'
);
assert.include(
data.favoriteFoods,
'cheese',
'"model.favoriteFoods" does not include the expected items'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,56 @@
---
id: 587d7fb6367417b2b2512c09
title: Creare e salvare un record di un modello
challengeType: 2
forumTopicId: 301536
dashedName: create-and-save-a-record-of-a-model
---
# --description--
In questa sfida dovrai creare e salvare un record di un modello.
# --instructions--
All'interno della funzione `createAndSavePerson`, crea un'istanza di documento usando il costruttore del modello `Person` che hai costruito prima. Passa al costruttore un oggetto con i campi `name`, `age`e `favoriteFoods`. I loro tipi devono essere conformi a quelli di `personSchema`. Quindi, chiama il metodo `document.save()` sull'istanza di documento restituita. Passa ad essa una callback usando la convenzione di Node. Questo è un modello comune; tutti i metodi CRUD seguenti prendono una funzione di callback come questa come ultimo argomento.
```js
/* Example */
// ...
person.save(function(err, data) {
// ...do your stuff here...
});
```
# --hints--
Si dovrebbe creare e salvare con successo un elemento del database
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/create-and-save-person').then(
(data) => {
assert.isString(data.name, '"item.name" should be a String');
assert.isNumber(data.age, '28', '"item.age" should be a Number');
assert.isArray(
data.favoriteFoods,
'"item.favoriteFoods" should be an Array'
);
assert.equal(data.__v, 0, 'The db item should be not previously edited');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,68 @@
---
id: 587d7fb7367417b2b2512c0a
title: Creare diversi record con model.create()
challengeType: 2
forumTopicId: 301537
dashedName: create-many-records-with-model-create
---
# --description--
A volte avrai bisogno di creare molte istanze dei tuoi modelli, ad esempio quando fai il seeding (semina) di un database con i dati iniziali. `Model.create()` prende un array di oggetti come `[{name: 'John', ...}, {...}, ...]` come primo argomento, e li salva tutti nel database.
# --instructions--
Modifica la funzione `createManyPeople` per creare molte persone usando `Model.create()` con l'argomento `arrayOfPeople`.
**Nota:** Puoi riutilizzare il modello che hai istanziato nell'esercizio precedente.
# --hints--
La creazione di molti oggetti db contemporaneamente dovrebbe avere successo
```js
(getUserInput) =>
$.ajax({
url: getUserInput('url') + '/_api/create-many-people',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify([
{ name: 'John', age: 24, favoriteFoods: ['pizza', 'salad'] },
{ name: 'Mary', age: 21, favoriteFoods: ['onions', 'chicken'] }
])
}).then(
(data) => {
assert.isArray(data, 'the response should be an array');
assert.equal(
data.length,
2,
'the response does not contain the expected number of items'
);
assert.equal(data[0].name, 'John', 'The first item is not correct');
assert.equal(
data[0].__v,
0,
'The first item should be not previously edited'
);
assert.equal(data[1].name, 'Mary', 'The second item is not correct');
assert.equal(
data[1].__v,
0,
'The second item should be not previously edited'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,57 @@
---
id: 587d7fb8367417b2b2512c11
title: Eliminare molti documenti con model.remove()
challengeType: 2
forumTopicId: 301538
dashedName: delete-many-documents-with-model-remove
---
# --description--
`Model.remove()` è utile per eliminare tutti i documenti corrispondenti ai criteri indicati.
# --instructions--
Modifica la funzione `removeManyPeople` per eliminare tutte le persone il cui nome è all'interno della variabile `nameToRemove`, usando `Model.remove()`. Passalo a un documento di query con il campo `name` impostato e una callback.
**Nota:** `Model.remove()` non restituisce il documento eliminato, ma un oggetto JSON contenente l'esito dell'operazione e il numero di elementi interessati. Non dimenticate di passarlo alla callback `done()`, dal momento che lo utilizzeremo nei test.
# --hints--
L'eliminazione di molti oggetti contemporaneamente dovrebbe avere successo
```js
(getUserInput) =>
$.ajax({
url: getUserInput('url') + '/_api/remove-many-people',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify([
{ name: 'Mary', age: 16, favoriteFoods: ['lollipop'] },
{ name: 'Mary', age: 21, favoriteFoods: ['steak'] }
])
}).then(
(data) => {
assert.isTrue(!!data.ok, 'The mongo stats are not what expected');
assert.equal(
data.n,
2,
'The number of items affected is not what expected'
);
assert.equal(data.count, 0, 'the db items count is not what expected');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,53 @@
---
id: 587d7fb8367417b2b2512c10
title: Eliminare un documento usando model.findByIdAndRemove
challengeType: 2
forumTopicId: 301539
dashedName: delete-one-document-using-model-findbyidandremove
---
# --description--
`findByIdAndRemove` e `findOneAndRemove` sono come i metodi di aggiornamento precedenti. Passano il documento rimosso al database. Come al solito, usa l'argomento `personId` della funzione come chiave di ricerca.
# --instructions--
Modifica la funzione `removeById` in modo che elimini una persona in base al suo `_id`. È necessario utilizzare i metodi `findByIdAndRemove()` o `findOneAndRemove()`.
# --hints--
L'eliminazione di un elemento dovrebbe avere successo
```js
(getUserInput) =>
$.post(getUserInput('url') + '/_api/remove-one-person', {
name: 'Jason Bourne',
age: 36,
favoriteFoods: ['apples']
}).then(
(data) => {
assert.equal(data.name, 'Jason Bourne', 'item.name is not what expected');
assert.equal(data.age, 36, 'item.age is not what expected');
assert.deepEqual(
data.favoriteFoods,
['apples'],
'item.favoriteFoods is not what expected'
);
assert.equal(data.__v, 0);
assert.equal(data.count, 0, 'the db items count is not what expected');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,85 @@
---
id: 587d7fb6367417b2b2512c06
title: Installare e configurare Mongoose
challengeType: 2
forumTopicId: 301540
dashedName: install-and-set-up-mongoose
---
# --description--
Lavorare su queste sfide ti porterà a scrivere il tuo codice utilizzando uno dei seguenti metodi:
- Clonare [questo repository GitHub](https://github.com/freeCodeCamp/boilerplate-mongomongoose/) e completare queste sfide localmente.
- Usare [la nostra bozza di progetto su Replit](https://replit.com/github/freeCodeCamp/boilerplate-mongomongoose) per completare queste sfide.
- Usa un costruttore di siti a tua scelta per completare il progetto. Assicurati di incorporare tutti i file dal nostro repository GitHub.
Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata pubblicamente da qualche parte. Quindi invia l'URL nel campo `Solution Link`.
In questa sfida, imposterai un database MongoDB Atlas e importerai i pacchetti necessari per connetterti ad esso.
Segui <a href='https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/' rel='noopener noreferrer' target='_blank'>questo tutorial</a> per impostare un database ospitato su MongoDB Atlas.
# --instructions--
Aggiungi `mongodb` e `mongoose` al `package.json` del progetto. Poi, richiedi mongoose come `mongoose` in `myApp.js`. Crea un file `.env` e aggiungi una variabile `MONGO_URI` ad esso. Il suo valore dovrebbe essere l'URI del database MongoDB Atlas. Assicurati di racchiudere l'URI tra virgolette singole o doppie, e ricorda che non puoi usare spazi attorno al segno `=` nelle variabili d'ambiente. Ad esempio, `MONGO_URI='VALUE'`. Quando hai finito, connettiti al database usando la seguente sintassi:
```js
mongoose.connect(<Your URI>, { useNewUrlParser: true, useUnifiedTopology: true });
```
# --hints--
la dipendenza "mongodb" dovrebbe essere specificata in package.json
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/file/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.property(packJson.dependencies, 'mongodb');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
la dipendenza "mongoose" dovrebbe essere specificata in package.json
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/file/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.property(packJson.dependencies, 'mongoose');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
"mongoose" dovrebbe essere connesso a un database
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/is-mongoose-ok').then(
(data) => {
assert.isTrue(data.isMongooseOk, 'mongoose is not connected');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,54 @@
---
id: 587d7fb8367417b2b2512c0e
title: 'Eseguire classici aggiornamenti eseguendo Find, Edit e Save'
challengeType: 2
forumTopicId: 301541
dashedName: perform-classic-updates-by-running-find-edit-then-save
---
# --description--
Nei bei tempi andati, questo era quello che dovevi fare se volevi modificare un documento, ed essere in grado di usarlo in qualche modo (ad esempio restituendolo in una risposta del server). Mongoose ha un metodo di aggiornamento dedicato: `Model.update()`. Esso è legato al driver di basso livello di mongo. Può modificare contemporaneamente più documenti che corrispondono a determinati criteri, ma non restituisce il documento aggiornato, solo un messaggio di 'stato'. Inoltre, rende difficile le validazioni del modello, perché chiama direttamente il driver di mongo.
# --instructions--
Modifica la funzione `findEditThenSave` per trovare una persona in base al suo `_id` (utilizza uno qualsiasi dei metodi visti in precedenza) con il parametro `personId` come chiave di ricerca. Aggiungi `"hamburger"` alla lista dei `favoriteFoods` della persona (puoi usare `Array.push()`). Quindi - all'interno della callback find - salva (`save()`) la `Person` aggiornata.
**Nota:** Potrebbe essere complicato, se nel tuo Schema, hai dichiarato `favoriteFoods` come Array, senza specificare il tipo (cioè `[String]`). In questo caso, `favoriteFoods` prende di default il tipo misto, e devi contrassegnarlo manualmente come modificato utilizzando `document.markModified('edited-field')`. Vedi la [Documentazione di Mongoose](https://mongoosejs.com/docs/schematypes.html#Mixed)
# --hints--
Il Find-edit-update di un elemento dovrebbe avere successo
```js
(getUserInput) =>
$.post(getUserInput('url') + '/_api/find-edit-save', {
name: 'Poldo',
age: 40,
favoriteFoods: ['spaghetti']
}).then(
(data) => {
assert.equal(data.name, 'Poldo', 'item.name is not what is expected');
assert.equal(data.age, 40, 'item.age is not what expected');
assert.deepEqual(
data.favoriteFoods,
['spaghetti', 'hamburger'],
'item.favoriteFoods is not what expected'
);
assert.equal(data.__v, 1, 'The item should be previously edited');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,58 @@
---
id: 587d7fb8367417b2b2512c0f
title: Eseguire nuovi aggiornamenti su un documento utilizzando model.findOneAndUpdate()
challengeType: 2
forumTopicId: 301542
dashedName: perform-new-updates-on-a-document-using-model-findoneandupdate
---
# --description--
Le versioni recenti di Mongoose hanno metodi per semplificare l'aggiornamento dei documenti. Alcune caratteristiche più avanzate (cioè gli agganci pre/post validazione) si comportano in modo diverso con questo approccio, quindi il metodo classico è ancora utile in molte situazioni. `findByIdAndUpdate()` può essere usato durante la ricerca tramite id.
# --instructions--
Modifica la funzione `findAndUpdate` per trovare una persona in base al suo `Name` e impostare l'età della persona a `20`. Utilizza il parametro `personName` della funzione come chiave di ricerca.
**Nota:** Dovresti restituire il documento aggiornato. Per farlo, dovresti passare il documento di opzioni `{ new: true }` come terzo argomento a `findOneAndUpdate()`. Per impostazione predefinita, questi metodi restituiscono l'oggetto non modificato.
# --hints--
findOneAndUpdate su un elemento dovrebbe avere successo
```js
(getUserInput) =>
$.post(getUserInput('url') + '/_api/find-one-update', {
name: 'Dorian Gray',
age: 35,
favoriteFoods: ['unknown']
}).then(
(data) => {
assert.equal(data.name, 'Dorian Gray', 'item.name is not what expected');
assert.equal(data.age, 20, 'item.age is not what expected');
assert.deepEqual(
data.favoriteFoods,
['unknown'],
'item.favoriteFoods is not what expected'
);
assert.equal(
data.__v,
0,
'findOneAndUpdate does not increment version by design!'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,53 @@
---
id: 587d7fb7367417b2b2512c0b
title: Usare model.find() per fare ricerche nel database
challengeType: 2
forumTopicId: 301543
dashedName: use-model-find-to-search-your-database
---
# --description--
Nel suo uso più semplice, `Model.find()` accetta un documento di query (un oggetto JSON) come primo argomento, quindi una callback. Restituisce un array di corrispondenze. Supporta una gamma estremamente ampia di opzioni di ricerca. Per approfondimenti leggi la documentazione.
# --instructions--
Modifica la funzione `findPeopleByName` per trovare tutte le persone che hanno un dato nome, usando <code>Model.find() -\> [Person]</code>
Usa l'argomento `personName` della funzione come chiave di ricerca.
# --hints--
La ricerca di tutti gli elementi corrispondenti a un criterio dovrebbe avere successo
```js
(getUserInput) =>
$.post(getUserInput('url') + '/_api/find-all-by-name', {
name: 'r@nd0mN4m3',
age: 24,
favoriteFoods: ['pizza']
}).then(
(data) => {
assert.isArray(data, 'the response should be an Array');
assert.equal(
data[0].name,
'r@nd0mN4m3',
'item.name is not what expected'
);
assert.equal(data[0].__v, 0, 'The item should be not previously edited');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,48 @@
---
id: 587d7fb7367417b2b2512c0d
title: Usare model.findById() per cercare nel database in base all'_id
challengeType: 2
forumTopicId: 301544
dashedName: use-model-findbyid-to-search-your-database-by-id
---
# --description--
Quando si salva un documento, MongoDB aggiunge automaticamente il campo `_id` e lo imposta su una chiave alfanumerica univoca. La ricerca per `_id` è un'operazione estremamente frequente, quindi Mongoose fornisce un metodo dedicato ad essa.
# --instructions--
Modifica il `findPersonById` per trovare l'unica persona che abbia un certo `_id` utilizzando `Model.findById() -> Person`. Usa l'argomento `personId` della funzione come chiave di ricerca.
# --hints--
La ricerca di un elemento per Id dovrebbe avere successo
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/find-by-id').then(
(data) => {
assert.equal(data.name, 'test', 'item.name is not what expected');
assert.equal(data.age, 0, 'item.age is not what expected');
assert.deepEqual(
data.favoriteFoods,
['none'],
'item.favoriteFoods is not what expected'
);
assert.equal(data.__v, 0, 'The item should be not previously edited');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,51 @@
---
id: 587d7fb7367417b2b2512c0c
title: Usare model.findOne() per restituire un singolo documento corrispondente dal tuo database
challengeType: 2
forumTopicId: 301545
dashedName: use-model-findone-to-return-a-single-matching-document-from-your-database
---
# --description--
`Model.findOne()` si comporta come `Model.find()`, ma restituisce un solo documento (non un array), anche se ci sono più elementi. È particolarmente utile durante la ricerca per proprietà che hai dichiarato come unique (univoche).
# --instructions--
Modifica la funzione `findOneByFood` per trovare solo una persona che abbia un certo cibo nei preferiti della persona, usando `Model.findOne() -> Person`. Usa l'argomento `food` della funzione come chiave di ricerca.
# --hints--
La ricerca di un elemento dovrebbe avere successo
```js
(getUserInput) =>
$.post(getUserInput('url') + '/_api/find-one-by-food', {
name: 'Gary',
age: 46,
favoriteFoods: ['chicken salad']
}).then(
(data) => {
assert.equal(data.name, 'Gary', 'item.name is not what expected');
assert.deepEqual(
data.favoriteFoods,
['chicken salad'],
'item.favoriteFoods is not what expected'
);
assert.equal(data.__v, 0, 'The item should be not previously edited');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```