text:
# NodeJS - Aula 01 - Exercício
**Autor**: Igor luíz
**Github**: [Halfeld](https://github.com/Halfeld)
**Data**: 1457214015206

# Por que quando requisitamos ao nosso servidor de Query String, com o Chrome, ele executa 2 requisições, sendo a última "vazia"?

Pois em cada requisição, o Chrome também faz a solicitação de um _favicon_.

# Qual a diferença entre o GET e o POST?

Os dois são usados para fazer requisições no servidor, com a principal diferença entre os dois, o `GET` passa os parametros pela url, já o `POST` manda os parametros encapsuladod junto ao corpo da requisição.
As requisições do tipo `GET` são mais para leitura, e as do tipo `POST` são usadas para fazer alterações.

# Crie um Pokemon na nossa API com seu nome, depois modifique seu nome pelo seu User do Github, colocando aqui a resposta de cada passo.

### Cadastrando com o meu nome
```js
'use strict';

const http = require('http'),
      querystring = require('querystring');

const postData = querystring.stringify({

    name: 'Igor Luíz',
    type: 'Student'
});

const options = {

    host: 'webschool-io.herokuapp.com',
    method: 'POST',
    path: '/api/pokemons',
    headers: {
        'Content-Type'  : 'application/x-www-form-urlencoded',
        'Contetn-length': postData.length
    }
}

function callback(res) {

    let data = '';
    res.setEncoding('utf8');

    res.on('data', chunk => {
        data += chunk;
    });

    res.on('end', () => {
        console.log(`Efetuado cadastro: ${data}`);
    });
}

const req = http.request(options, callback);

req.write(postData);
req.end();
```

### Saída no terminal
```js
➜  class-3 git:(master) ✗ node create-pokemon.js
Efetuado cadastro: {"__v":0,"name":"Igor Luíz","type":"Student","_id":"56db4f19204b6b1100a5212e"}
```

### Modificando com o meu user do github
```js
'use strict';

const http = require('http'),
      querystring = require('querystring');

const postData = querystring.stringify({

    name: 'Halfeld',
    type: 'Student'
});

const options = {

    host: 'webschool-io.herokuapp.com',
    method: 'PUT',
    path: '/api/pokemons/56db4f19204b6b1100a5212e',
    headers: {
        'Content-Type'  : 'application/x-www-form-urlencoded',
        'Contetn-length': postData.length
    }
}

function callback(res) {

    let data = '';
    res.setEncoding('utf8');

    res.on('data', chunk => {
        data += chunk;
    });

    res.on('end', () => {
        console.log(`Atualizado cadastro: ${data}`);
    });
}

const req = http.request(options, callback);

req.write(postData);
req.end();
```

### Saída no terminal
```js
➜  class-3 git:(master) ✗ node update-pokemon.js
Efetuado cadastro: {"data":{"ok":1,"nModified":1,"n":1,"lastOp":"6258683737379176449","electionId":"565e25d106dca622271891c4"}}
```

# Depois faça o delete, criando o script para tal, colocando aqui a resposta.

```js

'use strict';

const http = require('http'),
      querystring = require('querystring');

const postData = querystring.stringify({

    name: 'Halfeld',
    type: 'Student'
});

const options = {

    host: 'webschool-io.herokuapp.com',
    method: 'DELETE',
    path: '/api/pokemons/56db4f19204b6b1100a5212e',
    headers: {
        'Content-Type'  : 'application/x-www-form-urlencoded',
        'Contetn-length': postData.length
    }
}

function callback(res) {

    res.setEncoding('utf8');

    res.on('end', () => {
        console.log('Cadastro removido');
    });
}

const req = http.request(options, callback);

req.write(postData);
req.end();
```

# Escolha uma API externa e crie um script para fazer um GET nela mostrando o resultado em HTML.

### Código
```js
'use strict';

const http = require('http');

const options = {

    host: 'pokeapi.co',
    method: "GET",
    path: '/api/v1/pokemon/',
    headers: {
        'Content-Type': 'application/json'
    }
};

function callback(res) {

    res.setEncoding('utf8');

    res.on('data', chunck => {
        console.log(chunck);
    });

    res.on('end', () => {
        console.log('Finalizado');
    });
}

const req = http.request(options, callback);
req.end();
```

### Saída
```js
➜  class-3 git:(master) ✗ node api-pokemon-request.js
{"meta": {"limit": 1, "next": "/api/v1/pokemon/?limit=1&offset=1", "offset": 0, "previous": null, "total_count": 778}, "objects": [{"abilities": [{"name": "run-away", "resource_uri": "/api/v1/ability/50/"}, {"name": "hustle", "resource_uri": "/api/v1/ability/55/"}, {"name": "guts", "resource_uri": "/api/v1/ability/62/"}], "attack": 56, "catch_rate": 0, "created": "2013-11-03T15:05:41.305777", "defense": 35, "descriptions": [{"name": "rattata_gen_1", "resource_uri": "/api/v1/description/290/"}, {"name": "rattata_gen_1", "resource_uri": "/api/v1/description/291/"}, {"name": "rattata_gen_1", "resource_uri": "/api/v1/description/292/"}, {"name": "rattata_gen_1", "resource_uri": "/api/v1/description/288/"}, {"name": "rattata_gen_1", "resource_uri": "/api/v1/description/289/"}, {"name": "rattata_gen_2", "resource_uri": "/api/v1/description/293/"}, {"name": "rattata_gen_2", "resource_uri": "/api/v1/description/294/"}, {"name": "rattata_gen_3", "resource_uri": "/api/v1/description/295/"}, {"name": "rattata_gen_3", "resource_uri": "/api/v1/description/296/"}, {"name": "rattata_gen_4", "resource_uri": "/api/v1/description/300/"}, {"name": "rattata_gen_3", "resource_uri": "/api/v1/des
cription/297/"}, {"name": "rattata_gen_4", "resource_uri": "/api/v1/description/298/"}, {"name": "rattata_gen_4", "resource_uri": "/api/v1/description/299/"}, {"name": "rattata_gen_5", "resource_uri": "/api/v1/description/301/"}], "egg_cycles": 0, "egg_groups": [{"name": "Ground", "resource_uri": "/api/v1/egg/5/"}], "ev_yield": "", "evolutions": [{"level": 20, "method": "level_up", "resource_uri": "/api/v1/pokemon/20/", "to": "Raticate"}], "exp": 51, "growth_rate": "", "happiness": 0, "height": "3", "hp": 30, "male_female_ratio": "", "modified": "2013-11-23T13:13:24.187255", "moves": [{"learn_type": "tutor", "name": "Covet", "resource_uri": "/api/v1/move/343/"}, {"learn_type": "machine", "name": "Wild-charge", "resource_uri": "/api/v1/move/528/"}, {"learn_type": "machine", "name": "Work-up", "resource_uri": "/api/v1/move/526/"}, {"learn_type": "egg move", "name": "Final-gambit", "resource_uri": "/api/v1/move/515/"}, {"learn_type": "machine", "name": "Retaliate", "resource_uri": "/api/v1/move/514/"}, {"learn_type": "machine", "name": "Round", "resource_uri": "/api/v1/move/496/"}, {"learn_type": "egg move", "name": "Revenge", "resource_uri": "/api/v1/move/279/"}, {"learn_type": "tutor", "name": "Zen-headbutt", "resource_uri": "/api/v1/move/428/"}, {"learn_type": "machine", "name": "Charge-beam", "resource_uri": "/api/v1/move/451/"}, {"learn_type": "machine", "name": "Grass-knot", "resource_uri": "/api/v1/move/447/"}, {"learn_type": "machine", "name": "Captivate", "resource_uri": "/api/v1/move/445/"}, {"learn_type": "level up", "level": 19, "name": "Sucker-punch", "resource_uri": "/api/v1/move/389/"}, {"learn_type": "egg move", "name": "Last-resort", "resource_uri": "/api/v1/move/387/"}, {"learn_type": "egg move", "name": "Me-first", "resource_uri": "/api/v1/move/382/"}, {"learn_type": "level up", "level": 25, "name": "Assurance", "resource_uri": "/api/v1/move/372/"}, {"learn_type": "machine", "name": "U-turn", "resource_uri": "/api/v1/move/369/"}, {"learn_type": "machine", "name": "Pluck", "resource_uri": "/api/v1/move/365/"}, {"learn_type": "machine", "name": "Natural-gift", "resource_uri": "/api/v1/move/363/"}, {"learn_type": "level up", "level": 22, "name": "Crunch", "resource_uri": "/api/v1/move/242/"}, {"learn_type": "tutor", "name": "Thunder-wave", "resource_uri": "/api/v1/move/86/"}, {"learn_type": "machine", "name": "Shock-wave", "resource_uri": "/api/v1/move/351/"}, {"learn_type": "machine", "name": "Secret-power", "resource_uri": "/api/v1/move/290/"}, {"learn_type": "level up", "level": 41, "name": "Endeavor", "resource_uri": "/api/v1/move/283/"}, {"learn_type": "machine", "name": "Taunt", "resource_uri": "/api/v1/move/269/"}, {"learn_type": "machine", "name": "Facade", "resource_uri": "/api/v1/move/263/"}, {"learn_type": "egg move", "name": "Uproar", "resource_uri": "/api/v1/move/253/"}, {"learn_type": "machine", "name": "Rain-dance", "resource_uri": "/api/v1/move/240/"}, {"learn_type": "machine", "name": "Ice-beam", "resource_uri": "/api/v1/move/58/"}, {"learn_type": "machine", "name": "Cut", "resource_uri": "/api/v1/move/15/"}, {"learn_type": "machine", "name": "Rock-smash", "resource_uri": "/api/v1/move/249/"}, {"learn_type": "machine", "name": "Shadow-ball", "resource_uri": "/api/v1/move/247/"}, {"learn_type": "machine", "name": "Sunny-day", "resource_uri": "/api/v1/move/241/"}, {"learn_type": "machine", "name": "Hidden-power", "resource_uri": "/api/v1/move/237/"}, {"learn_type": "machine", "name": "Iron-tail", "resource_uri": "/api/v1/move/231/"}, {"learn_type": "level up", "level": 27, "name": "Pursuit", "resource_uri": "/api/v1/move/228/"}, {"learn_type": "machine", "name": "Frustration", "resource_uri": "/api/v1/move/218/"}, {"learn_type": "machine", "name": "Return", "resource_uri": "/api/v1/move/216/"}, {"learn_type": "machine", "name": "Sleep-talk", "resource_uri": "/api/v1/move/214/"}, {"learn_type": "machine", "name": "Attract", "resource_uri": "/api/v1/move/213/"}, {"learn_type": "machine", "name": "Swagger", "resource_uri": "/api/v1/move/207/"}, {"learn_type": "machine", "name": "Endure", "resource_uri": "/api/v1/move/203/"}, {"learn_type": "machine", "name": "Icy-wind", "resource_uri": "/api/v1/move/196/"}, {"learn_type": "machine", "name": "Mud-slap", "resource_uri": "/api/v1/move/189/"}, {"learn_type": "machine", "name": "Protect", "resource_uri": "/api/v1/move/182/"}, {"learn_type": "egg move", "name": "Reversal", "resource_uri": "/api/v1/move/179/"}, {"learn_type": "machine", "name": "Curse", "resource_uri": "/api/v1/move/174/"}, {"learn_type": "machine", "name": "Snore", "resource_uri": "/api/v1/move/173/"}, {"learn_type": "egg move", "name": "Flame-wheel", "resource_uri": "/api/v1/move/172/"}, {"learn_type": "machine", "name": "Thief", "resource_uri": "/api/v1/move/168/"}, {"learn_type": "egg move", "name": "Fury-swipes", "resource_uri": "/api/v1/move/154/"}, {"learn_type": "machine", "name": "Defense-curl", "resource_uri": "/api/v1/move/111/"}, {"learn_type": "egg move", "name": "Screech", "resource_uri": "/api/v1/move/103/"}, {"learn_type": "egg move", "name": "Counter", "resource_uri": "/api/v1/move/68/"}, {"learn_type": "egg move", "name": "Bite", "resource_uri": "/api/v1/move/44/"}, {"learn_type": "machine", "name": "Headbutt", "resource_uri": "/api/v1/move/29/"}, {"learn_type": "machine", "name": "Substitute", "resource_uri": "/api/v1/move/164/"}, {"learn_type": "level up", "level": 34, "name": "Super-fang", "resource_uri": "/api/v1/move/162/"}, {"learn_type": "level up", "level": 14, "name": "Hyper-fang", "resource_uri": "/api/v1/move/158/"}, {"learn_type": "machine", "name": "Rest", "resource_uri": "/api/v1/move/156/"}, {"learn_type": "machine", "name": "Skull-bash", "resource_uri": "/api/v1/move/130/"}, {"learn_type": "machine", "name": "Swift", "resource_uri": "/api/v1/move/129/"}, {"learn_type": "machine", "name": "Bide", "resource_uri": "/api/v1/move/117/"}, {"learn_type": "level up", "level": 23, "name": "Focus-energy", "resource_uri": "/api/v1/move/116/"}, {"learn_type": "machine", "name": "Double-team", "resource_uri": "/api/v1/move/104/"}, {"learn_type": "machine", "name": "Mimic", "resource_uri": "/api/v1/move/102/"}, {"learn_type": "machine", "name": "Rage", "resource_uri": "/api/v1/move/99/"}, {"learn_type": "level up", "level": 7, "name": "Quick-attack", "resource_uri": "/api/v1/move/98/"}, {"learn_type": "machine", "name": "Toxic", "resource_uri": "/api/v1/move/92/"}, {"learn_type": "machine", "name": "Dig", "resource_uri": "/api/v1/move/91/"}, {"learn_type": "machine", "name": "Thunder", "resource_uri": "/api/v1/move/87/"}, {"learn_type": "machine", "name": "Thunderbolt", "resource_uri": "/api/v1/move/85/"}, {"learn_type": "machine", "name": "Bubblebeam", "resource_uri": "/api/v1/move/61/"}, {"learn_typ
e": "machine", "name": "Blizzard", "resource_uri": "/api/v1/move/59/"}, {"learn_type": "machine", "name": "Water-gun", "resource_uri": "/api/v1/move/55/"}, {"learn_type": "level up", "level": 1, "name": "Tail-whip", "resource_uri": "/api/v1/move/39/"}, {"learn_type": "machine", "name": "Double-edge", "resource_uri": "/api/v1/move/38/"}, {"learn_type": "machine", "name": "Take-down", "resource_uri": "/api/v1/move/36/"}, {"learn_type": "machine", "name": "Body-slam", "resource_uri": "/api/v1/move/34/"}, {"learn_type": "level up", "level": 1, "name": "Tackle", "resource_uri": "/api/v1/move/33/"}], "name": "Rattata", "national_id": 19, "pkdx_id": 19, "resource_uri": "/api/v1/pokemon/19/", "sp_atk": 25, "sp_def": 35, "species": "", "speed": 72, "sprites": [{"name": "rattata", "resource_uri": "/api/v1/sprite/20/"}], "total": 0, "types": [{"name": "normal", "resource_uri": "/api/v1/type/1/"}], "weight": "35"}]}
Finalizado
```


text:
#NodeJS - Aula 03 - Exercícios
autor: Dariano Soares

##1. Por que quando requisitamos ao nosso servidor de Query String, **com o Chrome**, ele executa 2 requisições, sendo a última "vazia"?

São feita duas requisições uma para **trazer os dados** e a segunda para **trazer o favicon.ico**.

##2. Qual a DIFERENÇA entre o GET e o POST?
**GET** Recupera uma representação do recurso especificado. Uma requisição GET não deve alterar o estado do servidor, e é essencialmente uma operação de leitura.

**POST** É usado para se criar novos recursos no servidor. Usos típicos de requisição POST são o envio de formulários HTML e a adição de dados a uma base de dados.

Referencia -> Livro Pro Node.js para Desenvolvedores. Autor: Colin J. Ihrig
##3. Crie um Pokemon na nossa API com seu nome, depois modifique o seu nome pelo User do Github, colocando aqui a resposta de cada passo?

Após **adiconado** o pokemon Magneton a resposta foi:
```json
postData name=magneton&type=electric
Tamanho do postData 27
STATUS: 201

HEADERS: {
  "server": "Cowboy",
  "connection": "close",
  "x-powered-by": "Express",
  "access-control-allow-origin": "*",
  "content-type": "application/json; charset=utf-8",
  "content-length": "78",
  "etag": "W/\"4e-2gRVPek+rPQoqO15ybRyGw\"",
  "date": "Sat, 12 Dec 2015 22:03:33 GMT",
  "via": "1.1 vegur"
}
Dados finalizados: {
  "__v": 0,
  "name": "magneton",
  "type": "electric",
  "_id": "566c99b5103f631100175e62"
}
```
Após **atualizar** para o nome do usuário do gitHub o resultado foi:

```json
STATUS: 202
HEADERS: : {
  "server": "Cowboy",
  "connection": "close",
  "x-powered-by": "Express",
  "access-control-allow-origin": "*",
  "content-type": "application/json; charset=utf-8",
  "content-length": "108",
  "etag": "W/\"6c-Z+EiJ7w7xZR5Iy+oKrCjOA\"",
  "date": "Sat, 12 Dec 2015 22:11:15 GMT",
  "via": "1.1 vegur"
}

Dados finalizados: {
  "data": {
    "ok": 1,
    "nModified": 1,
    "n": 1,
    "lastOp": "6227523371689574401",
    "electionId": "565e25d106dca622271891c4"
  }
}
```
##4. **Depois faça o DELETE**, criando o script para tal, colocando aqui a resposta.
```json
STATUS: 204
HEADERS: {
  "server": "Cowboy",
  "content-length": "0",
  "connection": "close",
  "x-powered-by": "Express",
  "access-control-allow-origin": "*",
  "date": "Sat, 12 Dec 2015 22:15:17 GMT",
  "via": "1.1 vegur"
}
```
##5. Escolha uma **API externa** e crie um script para fazer um GET nela **mostrando o resultado com HTML**?
```js
'use strict';

const http = require('http');
const querystring = require('querystring');
const postData = querystring.stringify({
        parent: 'http%3A%2F%2Flabs.bluesoft.com.br'
      });

const options = {
        host: 'accounts.google.com'
      , method: 'GET'
      , path: '/o/oauth2/postmessageRelay'
      , headers: {
          'Content-Type': 'text/html'
        }
      };

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', (dados) =>  {
    data += dados;
  });
  res.on('end', () => {
    console.log('Dados finalizados: ', data)
  })
}

const req = http.request(options, callback);

req.on('error', (e) =>  {
  console.log('ERRO: ' + e.message);
});

req.end();
```
Retorno:

```html
<!DOCTYPE html>
<html lang=en>
   <meta charset=utf-8>
   <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
   <title>Error 404 (Not Found)!!1</title>
   <div id="af-error-container">
      <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
      <p><b>404.</b> <ins>That’s an error.</ins>
      <p>The requested URL was not found on this server. <ins>That’s all we know.</ins>
   </div>
</html>

```

repo_language: JavaScript

mime_type: text/plain


text:
# Node.js - Aula 03 - Exercício
**user:** [filipe1309](https://github.com/filipe1309)
**autor:** Filipe Leuch Bonfim

## Por que quando requisitamos ao nosso servidor de *Query String*, **com o Chrome**, ele executa 2 requisições, sendo a última "*vazia*"?

Este é um **bug**, [já conhecido do Chrome](http://crbug.com/39402), que envia um `request` a mais, solicitando o `favicon.ico` da aplicação.

## Qual a DIFERENÇA entre o GET e o POST?
A principal diferença entre estes métodos HTTP é a **visibilidade**.

|        -         | GET                                                                              | POST|
|------------------------------ | -------------------------------------------------------------------------------- |-----|
|**Quando usar**| poucos dados, e sem necessidade de segurança | grande quantidade de dados e necessidade de segurança|
|**Visibilidade** | os parâmetros do request são passados, de maneira visível, junto á URL | os parâmetros são encapsulados junto com a requisição HTTP, não sendo "visível" pela URL |
|**limite de caracteres** | Sim | Não |
|**Velocidade** | + Rápido | + Lento devido ao encapsulamento |
|**Tipo dos dados** | somente `string` | tanto `strings`, quanto dados binários |
|**Armazenamento [Cache/Favoritos]** | Sim | Não |

## Crie um Pokemon na nossa API com seu nome, depois modifique seu nome pelo seu User do Github.
#### Criando
##### http-request-post.js
```js
// ...
const postData = querystring.stringify({
        name: 'Filipe Leuch Bonfim'
      , type: 'estudante'
      });
// ...
```
```
> node http-request-post.js
postData name=Filipe%20Leuch%20Bonfim&type=estudante
Tamanho do postData 43
STATUS: 201
HEADERS:
{"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"90","etag":"W/\"5a-mfMhUZqUwCgMFkJAaSZciQ\"","date":"Thu, 25 Feb 2016 03:17:12 GMT","via":"1.1 vegur"}
Dados finalizados:  {"__v":0,"name":"Filipe Leuch Bonfim","type":"estudante","_id":"56ce7238beca0911007b63d4"}
```
#### Modificando
##### http-request-put.js
```js
// ...
const postData = querystring.stringify({
        name: 'filipe1309'
      , type: 'estudante'
      });
// ...
const options = {
        host: 'webschool-io.herokuapp.com'
      , method: 'PUT'
      , path: '/api/pokemons/56ce7238beca0911007b63d4'
      , headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        , 'Content-Length': postData.length
        }
      };
// ...
```
```
> node http-request-put.js
postData name=filipe1309&type=estudante
Tamanho do postData 30
STATUS: 202
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"108","etag":"W/\"6c-gdBvthDD89Q1hnGOpDGo5A\"","date":"Thu, 25 Feb 2016 03:19:07 GMT","via":"1.1 vegur"}
Dados finalizados:  {"data":{"ok":1,"nModified":1,"n":1,"lastOp":"6255063011229171713","electionId":"565e25d106dca622271891c4"}}
```

## **Depois faça o DELETE**, criando o script para tal, colocando aqui a resposta.
```
node http-request-del.js
STATUS: 204
HEADERS: {"server":"Cowboy","content-length":"0","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","date":"Thu, 25 Feb 2016 03:43:11 GMT","via":"1.1 vegur"}
Dados finalizados:
```

## Escolha uma **API externa** e crie um script para fazer um GET nela **mostrando o resultado com HTML**.
```js
'use strict';

const https = require('https');

const options = {
    host: 'hacker-news.firebaseio.com'
  , path: '/v0/item/11177200.json'
};

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    data += chunk;
  });
  res.on('end', function() {
    let data_json =  JSON.parse(data);
    let data_html = '<html><body><a href="';
    data_html += data_json.url + '"><h1>';
    data_html += data_json.title + '</h1></a></body></html>';

    console.log('Dados finalizados: ', data);
    console.log('Dados HTML: ',data_html);
  })
}

const req = https.request(options, callback);

req.on('error', function(e) {
  console.log('ERROOOO: ' + e.message);
});
req.end();
```
#### Saída
```
STATUS: 200
HEADERS: {"content-length":"559","content-type":"application/json; charset=utf-8","cache-control":"no-cache","strict-transport-security":"max-age=31556926; includeSubDomains; preload","connection":"close"}
Dados finalizados:  {"by":"sbuk","descendants":143,"id":11177200,"kids":[11177782,11179326,11179315,11179298,11178441,11178062,11178125,11178816,11178621,11178617,11179227,11179351,11178575,11178592,11178842,11178320,11177835,11177993,11179134,11178197,11177614,11177594,11177730,11178786,11177924,11178156,11178104,11178544,11177437,11179222],"score":527,"time":1456429470,"title":"Microsoft, Google, Facebook Back Apple in Blocked Phone Case","type":"story","url":"http://www.bloomberg.com/news/articles/2016-02-25/microsoft-says-it-will-file-an-amicus-brief-to-support-apple"}
Dados HTML:  <html><body><a href="http://www.bloomberg.com/news/articles/2016-02-25/microsoft-says-it-will-file-an-amicus-brief-to-support-apple"><h1>Microsoft, Google, Facebook Back Apple in Blocked Phone Case</h1></a></body></html>
```


text:
# Node.js - Aula 03 - Exercício

**user:** [xereda](https://github.com/xereda)

**autor:** Jackson Ricardo Schroeder

**date:** 1465274797795

## Por que quando requisitamos ao nosso servidor de *Query String*, **com o Chrome**, ele executa 2 requisições, sendo a última "*vazia*"?

Isso realmente ocorre apenas no Google Chrome. O Google Chrome realiza mais uma requisição, mas dessa vez para recuperar o favicon.ico, caso exista no servidor.

## Qual a DIFERENÇA entre o GET e o POST?

Embora o método POST também retorne informações para o requisitante, convencionou-se que POST _(inserir/Create)_ seria um método mais adequado para criar um novo documento, ficando para o GET o uso na recuperação das informações _(ler/Read/retrieve)_.

Já com base no **protocolo HTTP**, tecnicamente os dois métodos possuem algumas diferentes características. O método GET possui restrição de tamanho, e os parâmetros são repassados de forma explícita na requisição, num padrão URL (querystring). O método POST, tem suporte para envio de dados em maior volume e permite o envio de dados binários. Um exemplo de uso do método post são os formulários de upload de arquivos.

## Crie um Pokemon na nossa API com seu nome, depois modifique seu nome pelo seu User do Github.

**POST**

```js

// SCRIPT http-request-post.js
"use strict";

const http = require("http");

const options = {
  host: "webschool-io.herokuapp.com",
  method: "DELETE",
  path: "/api/pokemons/5756594a48075f1100eebd3b"
};

function callback(res) {

  console.log("STATUS: " + res.statusCode);
  console.log("HEADERS: " + JSON.stringify(res.headers));

  let data = "";

  res.setEncoding("utf8");
  res.on("data", (dados) => {

    data += dados;

  });

  res.on("end", () => {
    console.log("Dados Finalizados: " + data);
  });

}

const req = http.request(options, callback);

req.on("error", (e) => {
  console.log("ERROOOOO: " + e.message);
});

req.end();

```

```js

xereda@macminixereda:~/S/b/n/aula03$ node http-request-post.js
name=Jackson%20Ricardo%20Schroeder&type=aluno
STATUS: 201
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"91","etag":"W/\"5b-+kVJUd6DgHh39yVynxbEtQ\"","date":"Tue, 07 Jun 2016 05:20:42 GMT","via":"1.1 vegur"}
Dados Finalizados: {"__v":0,"name":"Jackson Ricardo Schroeder","type":"aluno","_id":"575659aa48075f1100eebd3c"}

```

**PUT**

```js

"use strict";

const http = require("http");
const querystring = require("querystring");

const postData = querystring.stringify({
  name: "xereda",
  type: "aluno"
});

const options = {
  host: "webschool-io.herokuapp.com",
  method: "PUT",
  path: "/api/pokemons/575659aa48075f1100eebd3c",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
    "Content-length": postData.length
  }
};

function callback(res) {

  console.log("STATUS: " + res.statusCode);
  console.log("HEADERS: " + JSON.stringify(res.headers));

  let data = "";

  res.setEncoding("utf8");
  res.on("data", (dados) => {

    data += dados;

  });

  res.on("end", () => {
    console.log("Dados Finalizados: " + data);
  });

}

const req = http.request(options, callback);

req.on("error", (e) => {
  console.log("ERROOOOO: " + e.message);
});

console.log(postData);

req.write(postData);
req.end();

```

```js

xereda@macminixereda:~/S/b/n/aula03$ node http-request-put.js
name=xereda&type=aluno
STATUS: 202
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"108","etag":"W/\"6c-KXqz1ydQydNDOG0DgOGl5A\"","date":"Tue, 07 Jun 2016 05:26:39 GMT","via":"1.1 vegur"}
Dados Finalizados: {"data":{"ok":1,"nModified":1,"n":1,"lastOp":"6293317649279483905","electionId":"56ee12f2563048036a1e77e7"}}

```

## **Depois faça o DELETE**, criando o script para tal, colocando aqui a resposta.

```js

"use strict";

const http = require("http");

const options = {
  host: "webschool-io.herokuapp.com",
  method: "DELETE",
  path: "/api/pokemons/575659aa48075f1100eebd3c"
};

function callback(res) {

  console.log("STATUS: " + res.statusCode);
  console.log("HEADERS: " + JSON.stringify(res.headers));

  let data = "";

  res.setEncoding("utf8");
  res.on("data", (dados) => {

    data += dados;

  });

  res.on("end", () => {
    console.log("Dados Finalizados: " + data);
  });

}

const req = http.request(options, callback);

req.on("error", (e) => {
  console.log("ERROOOOO: " + e.message);
});

req.end();

```

```js

xereda@macminixereda:~/S/b/n/aula03$ node http-request-delete.js
STATUS: 204
HEADERS: {"server":"Cowboy","content-length":"0","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","date":"Tue, 07 Jun 2016 05:30:25 GMT","via":"1.1 vegur"}
Dados Finalizados:

```

## Escolha uma **API externa** e crie um script para fazer um GET nela **mostrando o resultado com HTML**.

```js

'use strict';

const http = require('http');

const app = {
    createServer: () => {
        this.server = http.createServer((req, response) => {
            response.writeHead(200, { 'Content-Type': 'text/html' });
            http.get(app.optionsRequest, res => {
                let data = '';

                res.on('data', chunck => data += chunck);

                res.on('end', () => {
                    var json = JSON.parse(data)
                        , html = app.htmlHelper.build(json);
                    response.write(html);
                    response.end();
                });
            });
        });
    },
    htmlHelper: {
        build: (data) => {
            var html = '';
            html += app.htmlHelper.buildHeader();
            html += app.htmlHelper.buildBody(data);
            html += app.htmlHelper.buildFooter();
            return html;
        },
        buildHeader: () => {
            var html = '<!doctype html>' +
                '<html>' +
                '<head>' +
                '<meta charset="utf-8">' +
                '</head>' +
                '<body>';
            return html;
        },
        buildBody: data => {
          var html = '<h1>Usando API de times de futebol</h1>';
              html += '<ul>';
              let x = 0;
              let clube = [];

              for(clube in data.teams) {
                //console.log("x eh: "  + x);
                html += '<li>Nome do time: <b><i>' + data.teams[clube].name + '</i></b></li>';
                html += '<li>Apelido: <b><i>' + data.teams[clube].shortName + '</i></b></li>';
                html += '<li>Abreviatura: <b><i>' + data.teams[clube].code + '</i></b></li>';
                html += '<hr>';

              }
              html += '</ul>';
          return html;
        },
        buildFooter: () =>{ return '</body></html>' }
    },
    optionsRequest: {
        hostname: 'api.football-data.org',
        path: '/v1/soccerseasons/398/teams',
        headers: {
          'X-Auth-Token': 'bb738b800597467f98bc52e6e6093b69'
        }
    },
    listen: () => this.server.listen(3000, () => console.log('Estou pronto!')),
    server: null
};

app.createServer();
app.listen();

```

**HTML**

![](img/xereda_api_clubes.png)

```

<!doctype html><html><head><meta charset="utf-8"></head><body><h1>Usando API de times de futebol</h1><ul><li>Nome do time: <b><i>Manchester United FC</i></b></li><li>Apelido: <b><i>ManU</i></b></li><li>Abreviatura: <b><i>MUFC</i></b></li><hr><li>Nome do time: <b><i>Tottenham Hotspur FC</i></b></li><li>Apelido: <b><i>Spurs</i></b></li><li>Abreviatura: <b><i>THFC</i></b></li><hr><li>Nome do time: <b><i>AFC Bournemouth</i></b></li><li>Apelido: <b><i>Bournemouth</i></b></li><li>Abreviatura: <b><i>AFCB</i></b></li><hr><li>Nome do time: <b><i>Aston Villa FC</i></b></li><li>Apelido: <b><i>Aston Villa</i></b></li><li>Abreviatura: <b><i>AVFC</i></b></li><hr><li>Nome do time: <b><i>Everton FC</i></b></li><li>Apelido: <b><i>Everton</i></b></li><li>Abreviatura: <b><i>EFC</i></b></li><hr><li>Nome do time: <b><i>Watford FC</i></b></li><li>Apelido: <b><i>Watford</i></b></li><li>Abreviatura: <b><i>Watfordfc</i></b></li><hr><li>Nome do time: <b><i>Leicester City FC</i></b></li><li>Apelido: <b><i>Foxes</i></b></li><li>Abreviatura: <b><i>LCFC</i></b></li><hr><li>Nome do time: <b><i>Sunderland AFC</i></b></li><li>Apelido: <b><i>Sunderland</i></b></li><li>Abreviatura: <b><i>SUN</i></b></li><hr><li>Nome do time: <b><i>Norwich City FC</i></b></li><li>Apelido: <b><i>Norwich</i></b></li><li>Abreviatura: <b><i>NCFC</i></b></li><hr><li>Nome do time: <b><i>Crystal Palace FC</i></b></li><li>Apelido: <b><i>Crystal</i></b></li><li>Abreviatura: <b><i>CRY</i></b></li><hr><li>Nome do time: <b><i>Chelsea FC</i></b></li><li>Apelido: <b><i>Chelsea</i></b></li><li>Abreviatura: <b><i>CFC</i></b></li><hr><li>Nome do time: <b><i>Swansea City FC</i></b></li><li>Apelido: <b><i>Swans</i></b></li><li>Abreviatura: <b><i>SWA</i></b></li><hr><li>Nome do time: <b><i>Newcastle United FC</i></b></li><li>Apelido: <b><i>Newcastle</i></b></li><li>Abreviatura: <b><i>NUFC</i></b></li><hr><li>Nome do time: <b><i>Southampton FC</i></b></li><li>Apelido: <b><i>Southampton</i></b></li><li>Abreviatura: <b><i>SFC</i></b></li><hr><li>Nome do time: <b><i>Arsenal FC</i></b></li><li>Apelido: <b><i>Arsenal</i></b></li><li>Abreviatura: <b><i>AFC</i></b></li><hr><li>Nome do time: <b><i>West Ham United FC</i></b></li><li>Apelido: <b><i>West Ham</i></b></li><li>Abreviatura: <b><i>WHU</i></b></li><hr><li>Nome do time: <b><i>Stoke City FC</i></b></li><li>Apelido: <b><i>Stoke</i></b></li><li>Abreviatura: <b><i>SCFC</i></b></li><hr><li>Nome do time: <b><i>Liverpool FC</i></b></li><li>Apelido: <b><i>Liverpool</i></b></li><li>Abreviatura: <b><i>LFC</i></b></li><hr><li>Nome do time: <b><i>West Bromwich Albion FC</i></b></li><li>Apelido: <b><i>West Bromwich</i></b></li><li>Abreviatura: <b><i>WBA</i></b></li><hr><li>Nome do time: <b><i>Manchester City FC</i></b></li><li>Apelido: <b><i>ManCity</i></b></li><li>Abreviatura: <b><i>MCFC</i></b></li><hr></ul></body></html>

```


text:
# Node.js - Aula 03 - Exercício
**User:** [carloshenriqueribeiro](https://github.com/carloshenriqueribeiro)

**Autor:** Carlos Henrique Ribeiro

**Date:** 1452720577119

# 1. Por que quando requisitamos ao nosso servidor de Query String, **com o Chrome**, ele executa 2 requisições, sendo a última "vazia"?

Porque atumaticamente ele faz uma segunda requisição solicitando o "favicon.ico", esse favicon hoje é usado para melhor identificação da página, fica à esquena do title na aba do navegador.

# 2. Qual a **DIFERENÇA** entre o **GET** e o **POST**?

** GET **

O GET foi feito para se enviar pedidos para receber informações de uma url, e é usado para enviar parâmetros via URL (querystring). Ele possui uma limitação de caracteres em seu envio de 1.024 caracteres, o que torna o conteúdo bem limitado.

** POST **

Já o POST foi feito para enviar informações e não apenas consulta-las (como é o caso do GET). Os parâmetros não são enviados via url e o limite do POST é "ilimitado", sendo esse limite sendo apenas definido via servidor, o que geralmente garante o POST de bastante informação sem problema nenhum.

# 3. Crie um Pokemon na nossa API com o seu nome, depois modifique seu nome pelo seu user do Github, colocando aqui a resposta de cada passo.

~~~ js

//Criando o "Pokemon"

STATUS: 201
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"78","etag":"W/\"4e-GtkDpHj2/UkF+JW96KfJcQ\"","date":"Thru, 1 Ago 2017 18:39:01 GMT","via":"1.1 vegur"}
Dados finalizados:  {"__v":0,"name":"Carlitos ","type":"aluno","_id":"5696c65a2f90f71100f42eca"}

//Removendo

STATUS: 202
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"108","etag":"W/\"6c-BsH4onU2gQgfl729cawThQ\"","date":"Thru, 1 Ago 2017 18:41:47 GMT","via":"1.1 vegur"}
Dados finalizados:  {"data":{"ok":1,"nModified":1,"n":1,"lastOp":"6239393325560889345","electionId":"565e25d106dca622271891c4"}}

~~~

# 4. Depois faça o DELETE, criando o script para tal, colocndo aqui a resposta.

~~~ js

//Excluindo

STATUS: 204
HEADERS: {"server":"Cowboy","content-length":"0","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","date":"Thru, 1 Ago 2017 18:53:47 GMT","via":"1.1 vegur"}
Dados finalizados:

~~~

# 5. Escolha uma API externa e crie um script para fazer um GET nela mostrando o resultado em HTML.

~~~ js
//API
host: 'pokeapi.co',
path: '/api/v1/type/?limit=10&offset=1'

//Retorno
STATUS: 200
HEADERS: {"server":"nginx/1.1.19","date":"Thru, 1 Ago 2017 19:32:47 GMT","content-type":"application/json","transfer-encoding":"chunked","connection":"close","vary":"Accept","x-frame-options":"SAMEORIGIN","cache-control":"s-maxage=360, max-age=360"}

Fighting

Flying

Poison

Ground

Rock

Bug

Ghost

Steel

Fire

Water

~~~


text:
# Node.js - Aula 03 - Exercício
**User:** ronal2do
**Author:** Ronaldo Lima
**Date:**  1468022470175

##### [Exercício-01](#por-que-quando-requisitamos-ao-nosso-servidor-de-query-string-com-o-chrome-ele-executa-2-requisi%C3%A7%C3%B5es-sendo-a-%C3%BAltima-vazia)

##### [Exercício-02](#qual-a-diferen%C3%A7a-entre-o-get-e-o-post)

##### [Exercício-03](#crie-um-pokemon-na-nossa-api-com-seu-nome-depois-modifique-seu-nome-pelo-seu-user-do-github-colocando-aqui-a-resposta-de-cada-passo)

##### [Exercício-04](#depois-fa%C3%A7a-o-delete-criando-o-script-para-tal-colocando-aqui-a-resposta)

##### [Exercício-05](#escolha-uma-api-externa-e-crie-um-script-para-fazer-um-get-nela-mostrando-o-resultado-em-html)

# Por que quando requisitamos ao nosso servidor de Query String, com o Chrome, ele executa 2 requisições, sendo a última "vazia"?

Pois em cada requisição, o Chrome também faz a solicitação de um `favicon`.

# Qual a diferença entre o GET e o POST?

O `GET` é utilizado para quando queremos acessar alguma informação no servidor, outra coisa, o mesmo é visualizado através da url(a querystring após o endereço do servidor), e só pode enviar texto.

O `POST` é utilizado para quando queremos gravar alguma informação no servidor, pode enviar diversos tipos de dados(texto, arquivos, etc...).

# Crie um Pokemon na nossa API com seu nome, depois modifique seu nome pelo seu User do Github, colocando aqui a resposta de cada passo.

### Cadastrando com o meu nome

```js
'use strict';

const http = require('http');
const querystring = require('querystring');
const postData = querystring.stringify({
        name: '2D Lima'
      , type: 'Lokoooo!'
      });
const options = {
        host: 'webschool-io.herokuapp.com'
      , path: '/api/pokemons'
      , method: 'POST'
      , headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        , 'Content-Length': postData.length
        }
      };

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', (chunk) =>  {
    data += chunk;
  });
  res.on('end', () => {
    console.log('Dados finalizados: ', data)
  })
}

const req = http.request(options, callback);

req.on('error', (e) =>  {
  console.log('ERROOOO: ' + e.message);
});
req.write(postData);
req.end();

```

### Saída no terminal
```js
STATUS: 201
HEADERS: {"server":"Cowboy","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"77","etag":"W/\"4d-K1XAJt0nixO1Ke2TlcK+0g\"","date":"Sat, 09 Jul 2016 02:39:50 GMT","via":"1.1 vegur"}
Dados finalizados:  {"__v":0,"name":"2D Lima","type":"Lokoooo!","_id":"578063f62d78cb11006de9c4"}
```

### Modificando com o meu user do github
```js
'use strict';

const http = require('http');
const querystring = require('querystring');
const postData = querystring.stringify({
        name: 'ronal2do'
      , type: 'Lokoo!'
      });
const options = {
        host: 'webschool-io.herokuapp.com'
      , path: '/api/pokemons/578063f62d78cb11006de9c4'
      , method: 'PUT'
      , headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        , 'Content-Length': postData.length
        }
      };

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', (chunk) =>  {
    data += chunk;
  });
  res.on('end', () => {
    console.log('Dados finalizados: ', data)
  })
}

const req = http.request(options, callback);

req.on('error', (e) =>  {
  console.log('ERROOOO: ' + e.message);
});
req.write(postData);
req.end();
```

### Saída no terminal
```js
STATUS: 202
HEADERS: {"server":"Cowboy","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"108","etag":"W/\"6c-KUssZB1YDVSRLM9IZUNAAA\"","date":"Sat, 09 Jul 2016 02:53:02 GMT","via":"1.1 vegur"}
Dados finalizados:  {"data":{"ok":1,"nModified":1,"n":1,"lastOp":"6305152788145897473","electionId":"576451dfece94f32689e021d"}}

```

# Depois faça o delete, criando o script para tal, colocando aqui a resposta.

```js

'use strict';

const http = require('http');
const querystring = require('querystring');
const postData = querystring.stringify({
        name: 'ronal2do'
      , type: 'Lokoo!'
      });
const options = {
        host: 'webschool-io.herokuapp.com'
      , path: '/api/pokemons/578063f62d78cb11006de9c4'
      , method: 'DELETE'
      , headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        , 'Content-Length': postData.length
        }
      };

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', (chunk) =>  {
    data += chunk;
  });
  res.on('end', () => {
    console.log('Dados finalizados: ', data)
  })
}

const req = http.request(options, callback);

req.on('error', (e) =>  {
  console.log('ERROOOO: ' + e.message);
});
req.write(postData);
req.end();

```

### Saída no terminal
```js
STATUS: 204
HEADERS: {"server":"Cowboy","content-length":"0","x-powered-by":"Express","access-control-allow-origin":"*","date":"Sat, 09 Jul 2016 02:57:29 GMT","via":"1.1 vegur"}
Dados finalizados:

```

# Escolha uma API externa e crie um script para fazer um GET nela mostrando o resultado em HTML.

### Código
```js
// API do Magic TCG

'use strict';

const http = require('http');

const options = {
  host: 'api.deckbrew.com'
, path: '/mtg/cards/about-face'
};

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', (chunk) =>  {
    data += chunk;
  });
  res.on('end', () => {
    console.log('Dados finalizados: ', data)
  })
}

const req = http.request(options, callback);

req.on('error', (e) =>  {
  console.log('ERROOOO: ' + e.message);
});
req.end();

```

### Resultado Terminal com JSON
```js
STATUS: 200
HEADERS: {"date":"Sat, 09 Jul 2016 03:04:03 GMT","content-type":"application/json; charset=utf-8","content-length":"1186","set-cookie":["__cfduid=d62533328f17b2bacebe1331b35537e781468033443; expires=Sun, 09-Jul-17 03:04:03 GMT; path=/; domain=.deckbrew.com; HttpOnly"],"access-control-allow-origin":"*","access-control-expose-headers":"link,content-length","cache-control":"public,max-age=3600","disclaimer":"This API is not produced, endorsed, supported, or affiliated with Wizards of the Coast.","license":"The textual information presented through this API about Magic: The Gathering is copyrighted by Wizards of the Coast.","pricing":"store.tcgplayer.com allows you to buy cards from any of our vendors, all at the same time, in a simple checkout experience. Shop, Compare & Save with TCGplayer.com!","strict-transport-security":"max-age=86400","via":"1.1 vegur","server":"cloudflare-nginx","cf-ray":"2bf88be07bef07bb-MIA"}
Dados finalizados:  {
  "name": "About Face",
  "id": "about-face",
  "url": "https://api.deckbrew.com/mtg/cards/about-face",
  "store_url": "http://store.tcgplayer.com/magic/urzas-legacy/about-face?partner=DECKBREW",
  "types": [
    "instant"
  ],
  "colors": [
    "red"
  ],
  "cmc": 1,
  "cost": "{R}",
  "text": "Switch target creature's power and toughness until end of turn.",
  "formats": {
    "commander": "legal",
    "legacy": "legal",
    "vintage": "legal"
  },
  "editions": [
    {
      "set": "Urza's Legacy",
      "set_id": "ULG",
      "rarity": "common",
      "artist": "Melissa A. Benson",
      "multiverse_id": 12414,
      "flavor": "The overconfident are the most vulnerable.",
      "number": "73",
      "layout": "normal",
      "price": {
        "low": 0,
        "median": 0,
        "high": 0
      },
      "url": "https://api.deckbrew.com/mtg/cards?multiverseid=12414",
      "image_url": "https://image.deckbrew.com/mtg/multiverseid/12414.jpg",
      "set_url": "https://api.deckbrew.com/mtg/sets/ULG",
      "store_url": "http://store.tcgplayer.com/magic/urzas-legacy/about-face?partner=DECKBREW",
      "html_url": "https://deckbrew.com/mtg/cards/12414"
    }
  ]
}

```

### Resultado HTML

```js
// API do Magic TCG

'use strict';

const http = require('http');
const json2Html = require('node-json2html');

const options = {
  host: 'api.deckbrew.com'
, path: '/mtg/cards/about-face'
};

function callback(res){
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));

    res.setEncoding('utf8');

    let dados = '';

    res.on('data', (chunk) => {
        dados += chunk;
    });

    res.on('end', () => {
        let js = JSON.parse(dados);

        console.log('<ul>');

            console.log('<li> Nome: ' + js.name + '</li>');
            console.log('<li> id: ' + js.id + '</li>');
            console.log('<li> url: ' + js.url + '</li>');
            console.log('<li> text: ' + js.text + '</li>');
            console.log('<li> power: ' + js.power + '</li>');

        console.log('<ul>');
    })
}

const req = http.request(options, callback);

req.on('erros', (e) => {
    console.log('ERRO: ' + e.message);
});

req.end();

```

```js
STATUS: 200
HEADERS: {"date":"Sat, 09 Jul 2016 03:31:51 GMT","content-type":"application/json; charset=utf-8","content-length":"1186","set-cookie":["__cfduid=ddf6689c13114b06f1204dd2355c37aac1468035111; expires=Sun, 09-Jul-17 03:31:51 GMT; path=/; domain=.deckbrew.com; HttpOnly"],"access-control-allow-origin":"*","access-control-expose-headers":"link,content-length","cache-control":"public,max-age=3600","disclaimer":"This API is not produced, endorsed, supported, or affiliated with Wizards of the Coast.","license":"The textual information presented through this API about Magic: The Gathering is copyrighted by Wizards of the Coast.","pricing":"store.tcgplayer.com allows you to buy cards from any of our vendors, all at the same time, in a simple checkout experience. Shop, Compare & Save with TCGplayer.com!","strict-transport-security":"max-age=86400","via":"1.1 vegur","server":"cloudflare-nginx","cf-ray":"2bf8b49549172e7b-MIA"}
<ul>
<li> Nome: About Face</li>
<li> id: about-face</li>
<li> url: https://api.deckbrew.com/mtg/cards/about-face</li>
<li> text: Switch target creature's power and toughness until end of turn.</li>
<li> power: undefined</li>
<ul>
sh-3.2#
```


text:
# Node.js - Aula 03 - Exercício
**user:** [DouglasHennrich](https://github.com/DouglasHennrich)

**autor:** Douglas Hennrich

## Por que quando requisitamos ao nosso servidor de *Query String*, **com o Chrome**, ele executa 2 requisições, sendo a última "*vazia*"?
Isso ocorre, pois o Chrome faz a primeira requisição para puxar os dados da `Querystring` e a segunda requisição é para puxar o `fav.icon` do site

## Qual a DIFERENÇA entre o GET e o POST?
* **GET**
  - As informações são enviadas como `String` anexada a `URL`
  - Limite de tamanho da mensagem a ser enviada
  - Envia somente `String`
  - Informações enviadas ficam em `cache`

* **POST**
  - As informações são encapsuladas junto ao corpo da requisição `HTTP` e não podem ser vistas na `URL`
  - Sem limites de comprimento da mensagem enviada
  - Envia qualquer tipo de dados
  - As informações enviadas **NÃO** ficam gravadas em `cache`

## Crie um Pokemon na nossa API com seu nome, depois modifique seu nome pelo seu User do Github.
```js
STATUS:  201
HEADERS:  {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"83","etag":"W/\"53-NXiCwjw6In/DOcTmzTUjpQ\"","date":"Sun, 13 Dec 2015 01:59:39 GMT","via":"1.1 vegur"}
Dados Finalizados:  {"__v":0,"name":"Douglas Hennrich","type":"aluno","_id":"566cd10b25ff7511008dcfd2"}
```
---
```js
STATUS:  202
HEADERS:  {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"108","etag":"W/\"6c-aCp4f3tJR0UHoIZ68ib41w\"","date":"Sun, 13 Dec 2015 02:00:48 GMT","via":"1.1 vegur"}
Dados Finalizados:  {"data":{"ok":1,"nModified":1,"n":1,"lastOp":"6227582526274142209","electionId":"565e25d106dca622271891c4"}}
```

## **Depois faça o DELETE**, criando o script para tal, colocando aqui a resposta.
```js
STATUS:  204
HEADERS:  {"server":"Cowboy","content-length":"0","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","date":"Sun, 13 Dec 2015 02:02:28 GMT","via":"1.1 vegur"}
Dados Finalizados:

```

## Escolha uma **API externa** e crie um script para fazer um GET nela **mostrando o resultado com HTML**.
```html
STATUS:  200
HEADERS:  {"content-type":"text/html","date":"Sun, 13 Dec 2015 02:20:00 GMT","connection":"close","transfer-encoding":"chunked"}
Dados finalizados:
<html><body><h1>Pokemons</h1><ul><li>Pokemon: Bulbassauro</li><li>Pokemon: Charmander</li><li>Pokemon: Squirtle</li><li>Pokemon: Pikachu</li></ul></body></html>
```


text:
# Node.js - Aula 03 - Exercício
**user:** [davidsonsns](https://github.com/davidsonsns)

**autor:** Davidson da Silva Nascimento

### Por que quando requisitamos ao nosso servidor de *Query String*, **com o Chrome**, ele executa 2 requisições, sendo a última "*vazia*"?
Na primeira requisição é enviado os dados normalmente. Na segunda o Chrome requisita o **favicon** ao servidor.

[Removendo requisição favicon no node.js](https://gist.github.com/kentbrew/763822)

### Qual a DIFERENÇA entre o GET e o POST?
#### GET
+ Requisita informações no serviço/api
+ Requisição feita totalmente via URL(dados enviados juntamente a url)
+ Tamanho limitado de capacidade de envio
+ Mais rápido devido sua simplicidade
+ Apenas dados do tipo texto pode ser enviado
+ Requisição armazenada em cache
+ Método(method) padrão de formulários
+ Limitado ao padrão ASCII
+ Para indicar o início dos dados é utilizado a interrogação **(?)**, e para se separar cada valor se usa o símbolo **&**

Exemplo:
```
http://www.url.com.br?valor1=be&valor2=mean
```
#### POST
+ Cria entidades no serviço/api
+ Dados enviados no corpo da requisição HTTP.
+ Sem limitação de espaço
+ O encaplulamento da mensagem gera uma demora no envio
+ Transposta qualquer tipo de dado
+ Pode usar o atributo “enctype” com o valor “multipart/form-data”, que faz uso do padrão UCS(Universal Multiple-Octet Coded Character Set)

Exemplo:
```
POST /servlet/default.jsp HTTP/1.1
Accept: text/plain; text/html
Accept-Language: en-gb
Connection: Keep-Alive
Host: localhost
Referer: http://localhost/ch8/SendDetails.htm
User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate

LastName=Magalhaes&FirstName=Guilherme
```

### Crie um Pokemon na nossa API com seu nome, depois modifique seu nome pelo seu User do Github.
##### Criado
```js
STATUS:201
HEADERS:{
   "server":"Cowboy",
   "connection":"close",
   "x-powered-by":"Express",
   "access-control-allow-origin":"*",
   "content-type":"application/json; charset=utf-8",
   "content-length":"86",
   "etag":"W/\"56-dg3rEt0+ozh6uDqbY0CXAQ\"",
   "date":"Tue, 22 Mar 2016 23:55:39 GMT",
   "via":"1.1 vegur"
}
Dados finalizados:{
   "__v":0,
   "name":"Davidson Nascimento",
   "type":"aluno",
   "_id":"56f1db7bcb11f71100f8d2b2"
}
```

##### Modificado
```js
STATUS:202
HEADERS:{
   "server":"Cowboy",
   "connection":"close",
   "x-powered-by":"Express",
   "access-control-allow-origin":"*",
   "content-type":"application/json; charset=utf-8",
   "content-length":"108",
   "etag":"W/\"6c-dn2tbrpwX9BFx5AlJ5P7/A\"",
   "date":"Tue, 22 Mar 2016 23:58:17 GMT",
   "via":"1.1 vegur"
}
Dados finalizados:{
   "data":{
      "ok":1,
      "nModified":1,
      "n":1,
      "lastOp":"6265030556581363713",
      "electionId":"56ee12f2563048036a1e77e7"
   }
}
```

### **Depois faça o DELETE**, criando o script para tal, colocando aqui a resposta.
```js
STATUS:204
HEADERS:{
   "server":"Cowboy",
   "content-length":"0",
   "connection":"close",
   "x-powered-by":"Express",
   "access-control-allow-origin":"*",
   "date":"Tue, 22 Mar 2016 23:59:47 GMT",
   "via":"1.1 vegur"
}
Dados finalizados:
```

### Escolha uma **API externa** e crie um script para fazer um GET nela **mostrando o resultado com HTML**.
#### GET
```js
// file: http-request.js
'use strict';

const http = require('http');

const options = {
    host: 'api.randomuser.me',
    path: '/?gender=female&nat=br',
    method: 'GET',
    headers: {
        'User-Agent': 'Chrome/46.0.2490.86',
        'Content-Type': 'text/html'
    }
};

function callback(res) {
    let status = 'STATUS: ' + res.statusCode;
    let headers = 'HEADERS: ' + JSON.stringify(res.headers);

    let data = '';

    res.setEncoding('utf8');
    res.on('data', (chunk) => {
        data += chunk;
    });
    res.on('end', () => {
        let body = '<html><body><h4>' + status + '</h4><br>' + headers + '<br><br><code>' + data + '</code></body></html>'
        console.log(body)
    })
}

const req = http.request(options, callback);

req.on('error', (e) => {
    console.log('ERROOOO: ' + e.message);
});
req.end();
```
#### Resultado
```js
<html><body><h4>STATUS: 200</h4><br>HEADERS: {"server":"nginx","date":"Wed, 23 Mar 2016 01:24:13 GMT","content-type":"application/json; charset=utf-8","transfer-encoding":"chunked","connection":"close","access-control-allow-origin":"*"}<br><code>{
    "results": [
        {
            "user": {
                "gender": "female",
                "name": {
                    "title": "ms",
                    "first": "samara",
                    "last": "rocha"
                },
                "location": {
                    "street": "3166 rua pará",
                    "city": "cabo frio",
                    "state": "goiás",
                    "zip": 44101
                },
                "email": "samara.rocha@example.com",
                "username": "smallmeercat214",
                "password": "april",
                "salt": "lJeLupaH",
                "md5": "93d85105384f191849047f1f5f604ecb",
                "sha1": "35acee66eea14c004f214819d11ab3bf92f07c8b",
                "sha256": "f7c94aaef6fdfe1553aa107025b9df633af578af7a5635ebd7075785cf1390b0",
                "registered": 1352011251,
                "dob": 1131595230,
                "phone": "(90) 5421-1840",
                "cell": "(58) 9894-6336",
                "picture": {
                    "large": "https://randomuser.me/api/portraits/women/67.jpg",
                    "medium": "https://randomuser.me/api/portraits/med/women/67.jpg",
                    "thumbnail": "https://randomuser.me/api/portraits/thumb/women/67.jpg"
                }
            }
        }
    ],
    "nationality": "BR",
    "seed": "0b39f06d3acac76c01",
    "version": "0.8"
}</code></body></html>
```


text:
# Node.js - Aula 02 - Exercício
**user:** [Pauloxt1](https://github.com/Pauloxt1)

**autor:** Paulo Roberto

## Por que quando requisitamos ao nosso servidor de *Query String*, **com o Chrome**, ele executa 2 requisições, sendo a última "*vazia*"?
!['Console log'](http://i.imgur.com/YU4k7xh.png)

Porque uma requisição ele efetua com o GET que nós mandamos e outra ele manda tentando achar o favicon da página.

## Qual a DIFERENÇA entre o GET e o POST?
GET: Dados são transportados via URL, por ser assim só é suportado strings e há um limite de caracteres. É mais rápido que o POST pelo fato de ser mais simples.

POST: Dados não são expóstos na URL e nesse caso pode ser transportado tanto dados do tipo string como binários não há limite de caracteres é um pouco mais lenta que o GET.

## Crie um Pokemon na nossa API com seu nome, depois modifique seu nome pelo seu User do Github.
```js
paulo@Paulo:~/workshop-be-mean/nodejs$ node create_pokemon.js
STATUS: 201
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"79","etag":"W/\"4f-FQst1JWQGV9Isx6b9QMehg\"","date":"Sat, 16 Jan 2016 17:37:40 GMT","via":"1.1 vegur"}
Dados finalizados {"__v":0,"name":"Paulo Roberto","type":"zeus","_id":"569a7fe41f61701100d42ac7"}
```
```js
paulo@Paulo:~/workshop-be-mean/nodejs$ node change_mon.js
STATUS: 202
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"108","etag":"W/\"6c-D2UU4v75j2T2occrW4VFWQ\"","date":"Sat, 16 Jan 2016 18:07:13 GMT","via":"1.1 vegur"}
Dados finalizados {"data":{"ok":1,"nModified":1,"n":1,"lastOp":"6240448465881530369","electionId":"565e25d106dca622271891c4"}}
```
## **Depois faça o DELETE**, criando o script para tal, colocando aqui a resposta.
```js
paulo@Paulo:~/workshop-be-mean/nodejs$ node delete_mon.js
STATUS: 204
HEADERS: {"server":"Cowboy","content-length":"0","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","date":"Sat, 16 Jan 2016 18:12:01 GMT","via":"1.1 vegur"}
Dados finalizados
```
## Escolha uma **API externa** e crie um script para fazer um GET nela **mostrando o resultado com HTML**.
Vamos usar a mesma API que usamos para inserir e deletar dados, com o seguinte script:
```js
// file: get-pokemons
'use strict';

const http = require('http');
var dados = '';

http.get({
	hostname: 'webschool-io.herokuapp.com',
	path: '/api/pokemons',
	port:80,
	agent: false
}, (response)=>{
	console.log('STATUS: '+response.statusCode);
	console.log('HEADERS: '+JSON.stringify(response.headers));
	response.on('data', function(data){
		dados += data;
	});
	response.on('end', function(){
		newServer();
	});
});

function newServer(){
	http.createServer(function(request, response){
		var pokemons = JSON.parse(dados);
		for(var key in pokemons){
			var pokemon = pokemons[key];
			response.write('<b>ID:</b> '+pokemon._id+' <b>Nome:</b> '+pokemon.name+' <b>Tipo:</b> '+pokemon.type+'<br>');
		}
		response.end();
	}).listen(3000, function(){
		console.log('Aguardando conexões na porta 3000');
	});
}
```
Obtivemos o seguinte o resultado:

!['Resultado'](http://i.imgur.com/geKbIv5.png)


text:
# Node.js - Aula 03 - Exercício

**user:** https://github.com/paulosilva92

**autor:** Paulo Roberto da Silva

**date:** Sat Mar 05 2016 00:51:06 GMT-0300 (BRT)

## Por que quando requisitamos ao nosso servidor de *Query String*, com o Chrome, ele executa 2 requisições, sendo a última "vazia"?

Porque a segunda requisição se trata de uma requisição do favicon.ico do site, como o script que foi implementado na aula não da essa informação sobre o caminho do favicon.ico, ele retorna vazio.

## Qual a diferença entre GET e o POST

O GET é utilizado para requisitar informações do servidor, já o POST é utilizado para enviar informações ao servidor para criação de uma entidade.

## Crie um Pokemon na nossa API com seu nome, depois modifique seu nome pelo seu User do Github, colocando aqui a resposta de cada passo.

#### Criação do pokemon com meu nome
```js
'use strict';

const http = require('http');
const querystring = require('querystring');
const postData = querystring.stringify({
        name: 'Paulo Roberto da Silva'
      , type: 'Aluno'
      });
const options = {
        host: 'webschool-io.herokuapp.com'
      , path: '/api/pokemons'
      , method: 'POST'
      , headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        , 'Content-Length': postData.length
        }
      };

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', (chunk) =>  {
    data += chunk;
  });
  res.on('end', () => {
    console.log('Dados finalizados: ', data)
  })
}

const req = http.request(options, callback);

req.on('error', (e) =>  {
  console.log('ERROOOO: ' + e.message);
});
req.write(postData);
req.end();
```

##### Reposta

```js
STATUS: 201
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"89","etag":"W/\"59-vUcwx+2vIgWhwIrlPOqnug\"","date":"Tue, 01 Mar 2016 00:38:04 GMT","via":"1.1 vegur"}
Dados finalizados:  {"__v":0,"name":"Paulo Roberto da Silva","type":"Aluno","_id":"56d4e46cd537501100aa9722"}
```

#### Modificando o nome para meu user do Github
```js
'use strict';

const http = require('http');
const querystring = require('querystring');
const postData = querystring.stringify({
        name: 'paulosilva92'
      });
const options = {
        host: 'webschool-io.herokuapp.com'
      , path: '/api/pokemons/56d4e46cd537501100aa9722'
      , method: 'PUT'
      , headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        , 'Content-Length': postData.length
        }
      };

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', (chunk) =>  {
    data += chunk;
  });
  res.on('end', () => {
    console.log('Dados finalizados: ', data)
  })
}

const req = http.request(options, callback);

req.on('error', (e) =>  {
  console.log('ERROOOO: ' + e.message);
});
req.write(postData);
req.end();
```

##### resposta

```js
➜  aulas git:(master) ✗ node http-request-put.js
STATUS: 202
HEADERS: {"server":"Cowboy","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"108","etag":"W/\"6c-cOYquFHX6hzfF+eAuo8bCw\"","date":"Tue, 01 Mar 2016 00:39:02 GMT","via":"1.1 vegur"}
Dados finalizados:  {"data":{"ok":1,"nModified":1,"n":1,"lastOp":"6256877183940165633","electionId":"565e25d106dca622271891c4"}}
```

## Depois faça o DELETE, criando o script para tal e colocando aqui a resposta.

```js
'use strict';

const http = require('http');
const querystring = require('querystring');
const postData = querystring.stringify({
        name: 'paulosilva92'
      });
const options = {
        host: 'webschool-io.herokuapp.com'
      , path: '/api/pokemons/56d4e46cd537501100aa9722'
      , method: 'DELETE'
      , headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        , 'Content-Length': postData.length
        }
      };

function callback(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));

  let data = '';

  res.setEncoding('utf8');
  res.on('data', (chunk) =>  {
    data += chunk;
  });
  res.on('end', () => {
    console.log('Dados finalizados: ', data)
  })
}

const req = http.request(options, callback);

req.on('error', (e) =>  {
  console.log('ERROOOO: ' + e.message);
});
//req.write(postData);
req.end();
```

##### reposta

```js
➜  aulas git:(master) ✗ node http-request-delete.js
STATUS: 204
HEADERS: {"server":"Cowboy","content-length":"0","connection":"close","x-powered-by":"Express","access-control-allow-origin":"*","date":"Wed, 02 Mar 2016 16:59:03 GMT","via":"1.1 vegur"}
Dados finalizados:
```

## Escolha uma API externa e crie um script para fazer um GET nela mostrando o resultado com HTML.

```js
'use strict';

const http = require('http');
var RESP = {
  name: 'resposta'
};

http.get({
  hostname : 'pokeapi.co',
  path: '/api/v2/language/5/',
},(response) => {
    let body = "";
    console.log('STATUS:'+ response.statusCode);
    console.log(response.headers);

    response.on('data', data=>{
      body += data;
    });

    response.on('end', function(){
       RESP.result = JSON.parse(body).name;
    });
});

http.createServer((request, response)=>{
  response.writeHead(200, {'Content-Type': 'text/html'});
  response.write('<h1>'+RESP.result+'<h1>');
  response.end();
}).listen(3000, function(){
  console.log('rodando nas porta 3000');
});
```


text:
# Node.js - Aula 06 - Exercícios

**User:** [matheusjkweber](https://github.com/matheusjkweber)

**Autor:** Matheus Jose Krumenauer Weber

**Date:** 1457207231956

## Crie um Schema com cada tipo explicado, inserindo tanto um objeto correto, como um objeto que desencadeie erros de validação padrão, criar especificamente:

### Com erros:
```js
require('./config.js');

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const _schema = {
	name: {type: String, match: /^S/, minlength: 3, maxlength:10},
	picture: Buffer,
	description: String,
	type: {type: String, maxlength: 100, minlength: 5},
	attack: { type: Number, min: 0, max: 100 },
	defense: { type: Number, min: 0, max: 100 },
	height: { type: Number, min: 0, max: 100 },
	create_at: {type: Date, default: Date.now},
	gender: {type:String, enum: ['male','female']},
	atacks: Schema.Types.Mixed,
	other_types: [String],
	active: Boolean
};

const pokemonSchema = new Schema(_schema);

console.log("Schema created.");

const buf3 = new Buffer('test');

const attacks = {name: "Thundershock", power: 50}
const pokemonModel ={
	name: "pi",
	picture: buf3,
	description: "lalala",
	type: "Fire",
	attak: 120,
	defense: -20,
	heigth: 120,
	gender: "none",
	atacks: attacks,
	other_type: ["leaf"],
	active: 1
}

var model = mongoose.model('pokemons', pokemonSchema);

var poke = new model(pokemonModel);

poke.save(function (err, data) {
  if (err) return console.log('ERRO: ', err);
  console.log('Inseriu: ', data)
})

module.exports = pokemonSchema;
```
```
Schema created.
ERRO:  { [ValidationError: pokemons validation failed]
  message: 'pokemons validation failed',
  name: 'ValidationError',
  errors:
   { gender:
      { [ValidatorError: `none` is not a valid enum value for path `gender`.]
        properties: [Object],
        message: '`none` is not a valid enum value for path `gender`.',
        name: 'ValidatorError',
        kind: 'enum',
        path: 'gender',
        value: 'none' },
     defense:
      { [ValidatorError: Path `defense` (-20) is less than minimum allowed value (0).]
        properties: [Object],
        message: 'Path `defense` (-20) is less than minimum allowed value (0).',
        name: 'ValidatorError',
        kind: 'min',
        path: 'defense',
        value: -20 },
     type:
      { [ValidatorError: Path `type` (`Fire`) is shorter than the minimum allowed length (5).]
        properties: [Object],
        message: 'Path `type` (`Fire`) is shorter than the minimum allowed length (5).',
        name: 'ValidatorError',
        kind: 'minlength',
        path: 'type',
        value: 'Fire' },
     name:
      { [ValidatorError: Path `name` is invalid (pi).]
        properties: [Object],
        message: 'Path `name` is invalid (pi).',
        name: 'ValidatorError',
        kind: 'regexp',
        path: 'name',
        value: 'pi' } } }
Mongoose default connection connected to mongodb://localhost/be-mean-pokemons
Mongoose default connection is open
```

### Sem erros de validação:
```js
require('./config.js');

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const _schema = {
	name: {type: String, minlength: 3, maxlength:20},
	picture: Buffer,
	description: String,
	type: {type: String, maxlength: 100, minlength: 3},
	attack: { type: Number, min: 0, max: 100 },
	defense: { type: Number, min: 0, max: 100 },
	height: { type: Number, min: 0, max: 100 },
	create_at: {type: Date, default: Date.now},
	gender: {type:String, enum: ['male','female']},
	atacks: Schema.Types.Mixed,
	other_types: [String],
	active: Boolean
};

const pokemonSchema = new Schema(_schema);

console.log("Schema created.");

const buf3 = new Buffer('test');

const attacks = {name: "Thundershock", power: 50}
const pokemonModel ={
	name: "charmanders",
	picture: buf3,
	description: "Pokemon de fogo lindao.",
	type: "Fire",
	attak: 17,
	defense: 8,
	heigth: 5,
	gender: "male",
	atacks: attacks,
	other_type: ["leaf"],
	active: 1
}

var model = mongoose.model('pokemons', pokemonSchema);

var poke = new model(pokemonModel);

poke.save(function (err, data) {
  if (err) return console.log('ERRO: ', err);
  console.log('Inseriu: ', data)
})

module.exports = pokemonSchema;
```

```
Schema created.
Mongoose default connection connected to mongodb://localhost/be-mean-pokemons
Mongoose default connection is open
Inseriu:  { create_at: Sat Mar 05 2016 17:17:20 GMT-0300 (BRT),
  other_types: [],
  _id: 56db3ed040db47d213d901eb,
  active: true,
  atacks: { name: 'Thundershock', power: 50 },
  gender: 'male',
  defense: 8,
  type: 'Fire',
  description: 'Pokemon de fogo lindao.',
  picture:
   Binary {
     _bsontype: 'Binary',
     sub_type: 0,
     position: 4,
     buffer: <Buffer 74 65 73 74> },
  name: 'charmanders',
  __v: 0 }

```
## Cadastre 3 pokemons de uma só vez. (pesquisar).
```js
require('./config.js');

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const _schema = {
	name: {type: String, minlength: 3, maxlength:20},
	picture: Buffer,
	description: String,
	type: {type: String, maxlength: 100, minlength: 3},
	attack: { type: Number, min: 0, max: 100 },
	defense: { type: Number, min: 0, max: 100 },
	height: { type: Number, min: 0, max: 100 },
	create_at: {type: Date, default: Date.now},
	gender: {type:String, enum: ['male','female']},
	atacks: Schema.Types.Mixed,
	other_types: [String],
	active: Boolean
};

const pokemonSchema = new Schema(_schema);

console.log("Schema created.");

const buf3 = new Buffer('test');

const attacks = {name: "Thundershock", power: 50}
const pokemonModel =[ {
	name: "Pikachu",
	picture: buf3,
	description: "Pokemon eletrico lindao.",
	type: "Eletric",
	attak: 20,
	defense: 5,
	heigth: 7,
	gender: "female",
	atacks: attacks,
	other_type: ["rat"],
	active: 1
}, {
	name: "Raichu",
	picture: buf3,
	description: "Pokemon eletrico lindao.",
	type: "Eletric",
	attak: 37,
	defense: 22,
	heigth: 15,
	gender: "female",
	atacks: attacks,
	other_type: ["rat"],
	active: 1
}, {
	name: "Pichu",
	picture: buf3,
	description: "Pokemon eletrico lindao.",
	type: "Eletric",
	attak: 12,
	defense: 5,
	heigth: 3,
	gender: "female",
	atacks: attacks,
	other_type: ["rat"],
	active: 1
}]

var model = mongoose.model('pokemons', pokemonSchema);

pokemonModel.forEach(function(data){
	console.log(data);

	var poke = new model(data);

	poke.save(function (err, data) {
	  if (err) return console.log('ERRO: ', err);
	  console.log('Inseriu: ', data)
	})
});

/*var poke = new model(pokemonModel);

poke.save(function (err, data) {
  if (err) return console.log('ERRO: ', err);
  console.log('Inseriu: ', data)
})*/

module.exports = pokemonSchema;
```
```
Mongoose default connection connected to mongodb://localhost/be-mean-pokemons
Mongoose default connection is open
Inseriu:  { create_at: Sat Mar 05 2016 17:22:16 GMT-0300 (BRT),
  other_types: [],
  _id: 56db3ff878d92438145403d7,
  active: true,
  atacks: { name: 'Thundershock', power: 50 },
  gender: 'female',
  defense: 5,
  type: 'Eletric',
  description: 'Pokemon eletrico lindao.',
  picture:
   Binary {
     _bsontype: 'Binary',
     sub_type: 0,
     position: 4,
     buffer: <Buffer 74 65 73 74> },
  name: 'Pikachu',
  __v: 0 }
Inseriu:  { create_at: Sat Mar 05 2016 17:22:16 GMT-0300 (BRT),
  other_types: [],
  _id: 56db3ff878d92438145403d8,
  active: true,
  atacks: { name: 'Thundershock', power: 50 },
  gender: 'female',
  defense: 22,
  type: 'Eletric',
  description: 'Pokemon eletrico lindao.',
  picture:
   Binary {
     _bsontype: 'Binary',
     sub_type: 0,
     position: 4,
     buffer: <Buffer 74 65 73 74> },
  name: 'Raichu',
  __v: 0 }
Inseriu:  { create_at: Sat Mar 05 2016 17:22:16 GMT-0300 (BRT),
  other_types: [],
  _id: 56db3ff878d92438145403d9,
  active: true,
  atacks: { name: 'Thundershock', power: 50 },
  gender: 'female',
  defense: 5,
  type: 'Eletric',
  description: 'Pokemon eletrico lindao.',
  picture:
   Binary {
     _bsontype: 'Binary',
     sub_type: 0,
     position: 4,
     buffer: <Buffer 74 65 73 74> },
  name: 'Pichu',
  __v: 0 }

```
## Busque todos os Pokemons com attack > 50 e height > 0.5:
```js
require('./config.js');

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const _schema = {
	name: {type: String, minlength: 3, maxlength:20},
	picture: Buffer,
	description: String,
	type: {type: String, maxlength: 100, minlength: 3},
	attack: { type: Number, min: 0, max: 100 },
	defense: { type: Number, min: 0, max: 100 },
	height: { type: Number, min: 0, max: 100 },
	create_at: {type: Date, default: Date.now},
	gender: {type:String, enum: ['male','female']},
	atacks: Schema.Types.Mixed,
	other_types: [String],
	active: Boolean
};

const pokemonSchema = new Schema(_schema);

var model = mongoose.model('pokemons', pokemonSchema);

const query = {attack: {$gt:50}, height: {$gt: 0.5}};

model.find(query, function (err, data) {
  if (err) return console.log('ERRO: ', err);
  console.log('Inseriu: ', data)
})

module.exports = pokemonSchema;
```
```
Mongoose default connection connected to mongodb://localhost/be-mean-pokemons
Mongoose default connection is open
Inseriu:  [ { create_at: Sat Mar 05 2016 17:25:32 GMT-0300 (BRT),
    other_types: [],
    moves: [ [Object] ],
    height: 5.2,
    attack: 100,
    type: 'fire',
    description: 'Salamandra de fogo evoluida',
    name: 'Charmeleon',
    _id: 56478345771dc8af7806b25f },
  { create_at: Sat Mar 05 2016 17:25:32 GMT-0300 (BRT),
    other_types: [],
    moves: [ [Object] ],
    height: 17,
    attack: 160,
    type: 'fire',
    description: 'Salamandra de fogo evoluida suprema',
    name: 'Charizard',
    _id: 56478346771dc8af7806b260 },
  { create_at: Sat Mar 05 2016 17:25:32 GMT-0300 (BRT),
    other_types: [],
    moves: [ [Object] ],
    height: 5,
    attack: 130,
    type: 'psychic',
    description: 'O senhor supremo do mundo pokemon',
    name: 'Mewtwo',
    _id: 56478348771dc8af7806b261 },
  { create_at: Sat Mar 05 2016 17:25:32 GMT-0300 (BRT),
    other_types: [],
    moves: [ 'patada', 'endurecer', [Object] ],
    height: 0.6,
    attack: 52,
    type: 'fogo',
    description: 'Esse é o cão chupando manga de fofinho',
    name: 'Charmander',
    _id: 564d10f258ed05ea2e341137 } ]
```
## Altere, inserindo, o Pokemon Nerdmon com attack igual a 49 e com os valores dos outros campos a sua escolha.
```js
require('./config.js');

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const _schema = {
	name: {type: String, minlength: 3, maxlength:20},
	picture: Buffer,
	description: String,
	type: {type: String, maxlength: 100, minlength: 3},
	attack: { type: Number, min: 0, max: 100 },
	defense: { type: Number, min: 0, max: 100 },
	height: { type: Number, min: 0, max: 100 },
	create_at: {type: Date, default: Date.now},
	gender: {type:String, enum: ['male','female']},
	atacks: Schema.Types.Mixed,
	other_types: [String],
	active: Boolean
};

const pokemonSchema = new Schema(_schema);

console.log("Schema created.");

const buf3 = new Buffer('test');

const attacks = {name: "Thundershock", power: 50}
const pokemonModel ={
	name: "Nerdmon",
	picture: buf3,
	description: "Pokemon de fogo lindao.",
	type: "Fire",
	attak: 49	,
	defense: 8,
	heigth: 5,
	gender: "male",
	atacks: attacks,
	other_type: ["leaf"],
	active: 1
}

var model = mongoose.model('pokemons', pokemonSchema);

const query = {name: /Nerdmon/i}
const mod = {$setOnInsert: pokemonModel}
const options = {upsert: true}

model.update(query, mod, options, function (err, data) {
  if (err) return console.log('ERRO: ', err);
  console.log('Alterou: ', data)
})

module.exports = pokemonSchema;
```
```
matheus@Math:~/Desktop/Desenvolvimento/workshop-be-mean/nodejs/class6$ node exercicio4.js
Schema created.
Mongoose default connection connected to mongodb://localhost/be-mean-pokemons
Mongoose default connection is open
Alterou:  { ok: 1,
  nModified: 0,
  n: 1,
  upserted: [ { index: 0, _id: 56db4181ca92b6ac012b6cf7 } ] }
```

## Remova todos os Pokemons com attack acima de 50.
```js
require('./config.js');

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const _schema = {
	name: {type: String, minlength: 3, maxlength:20},
	picture: Buffer,
	description: String,
	type: {type: String, maxlength: 100, minlength: 3},
	attack: { type: Number, min: 0, max: 100 },
	defense: { type: Number, min: 0, max: 100 },
	height: { type: Number, min: 0, max: 100 },
	create_at: {type: Date, default: Date.now},
	gender: {type:String, enum: ['male','female']},
	atacks: Schema.Types.Mixed,
	other_types: [String],
	active: Boolean
};

const pokemonSchema = new Schema(_schema);

var model = mongoose.model('pokemons', pokemonSchema);

const query = {atack: {$gt: 50}}

model.remove(query, function (err, data) {
  if (err) return console.log('ERRO: ', err);
  console.log('Removeu: ', data)
})

module.exports = pokemonSchema;
```
```
Removeu:  { result: { ok: 1, n: 0 },
  connection:
   EventEmitter {
     domain: null,
     _events:
      { close: [Object],
        error: [Object],
        timeout: [Object],
        parseError: [Object],
        connect: [Function] },
     _eventsCount: 5,
     _maxListeners: undefined,
     options:
      { socketOptions: {},
        auto_reconnect: true,
        host: 'localhost',
        port: 27017,
        cursorFactory: [Object],
        reconnect: true,
        emitError: true,
        size: 5,
        disconnectHandler: [Object],
        bson: {},
        messageHandler: [Function],
        wireProtocolHandler: {} },
     id: 0,
     logger: { className: 'Connection' },
     bson: {},
     tag: undefined,
     messageHandler: [Function],
     maxBsonMessageSize: 67108864,
     port: 27017,
     host: 'localhost',
     keepAlive: true,
     keepAliveInitialDelay: 0,
     noDelay: true,
     connectionTimeout: 0,
     socketTimeout: 0,
     destroyed: false,
     domainSocket: false,
     singleBufferSerializtion: true,
     serializationFunction: 'toBinUnified',
     ca: null,
     cert: null,
     key: null,
     passphrase: null,
     ssl: false,
     rejectUnauthorized: false,
     checkServerIdentity: true,
     responseOptions: { promoteLongs: true },
     flushing: false,
     queue: [],
     connection:
      Socket {
        _connecting: false,
        _hadError: false,
        _handle: [Object],
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: true,
        domain: null,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: false,
        destroyed: false,
        bytesRead: 250,
        _bytesDispatched: 229,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        read: [Function],
        _consuming: true },
     writeStream: null,
     hashedName: '29bafad3b32b11dc7ce934204952515ea5984b3c',
     buffer: null,
     sizeOfMessage: 0,
     bytesRead: 0,
     stubBuffer: null } }
```


text:
# Node.js - Aula 06 - Exercício

**user:** [Pauloxt1](https://github.com/Pauloxt1)

**autor:** Paulo Roberto

## Crie um Schema com cada tipo explicado, inserindo tanto um objeto correto, como um objeto que desencadeie erros de validação padrão, criar especificamente:

* 1.1. para String: `enum`, `match`, `maxlength` e `minlength`
* 1.2.  para Number: `max` e `min`

Objeto correto:
```js
const fs = require('fs');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

var enu = {
  values: ['Paulo'],
  message: 'Ocorreu um erro documento `{PATH}` com valor `{VALUE}` do tipo `{TYPE}`'
}

// user Schema
const _schema = {
    login:{type:String, minlength:2, maxlength:10, match: /^\w/, enum: enu},
    active: Boolean,
    date_register:Date,
    profile_image: {data: Buffer, contentType: String},
    friends:[{type: Schema.Types.ObjectId, ref: 'users'}],
    profile_tags: [String],
    age: {type:Number, max:100, min:12},
    favorites: Schema.Types.Mixed
}

const userSchema = new Schema(_schema);
const userModel = mongoose.model('users', userSchema);

const readImg = fs.readFileSync('default.jpg');

const user = new userModel({
    login:'Paulo',
    active:1,
    date_register: Date.now(),
    friends:["56a5953b1416d13a8e98715b"],
    profile_image:{data:readImg, contentType:'image/jpeg'},
    profile_tags:['batata', 'tag1'],
    age:16,
    favorites:[{id:null, data:Date.now()}]
});

user.save(function(err, result){
    if(err) console.log(err);
    console.log(result);
});
```

```shell
paulo@Paulo:~/workshop-be-mean/nodejs/exercicio6$ node app.js
Mongoose default connection connected to mongodb://localhost/exercicio6
Mongoose default connection is open
{ profile_image:
   { contentType: 'image/jpeg',
     data:
      Binary {
        _bsontype: 'Binary',
        sub_type: 0,
        position: 1984,
        buffer: <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff db 00 84 00 09 06 07 12 10 10 15 0f 10 10 10 16 15 17 16 18 18 18 11 15 15 15 17 16 16 ... > } },
  friends: [ 56a5953b1416d13a8e98715b ],
  profile_tags: [ 'batata', 'tag1' ],
  _id: 56a5965c09badc7e2bd93acc,
  favorites: [ { id: null, data: 1453692508444 } ],
  age: 16,
  date_register: Mon Jan 25 2016 01:28:28 GMT-0200 (BRST),
  active: true,
  login: 'Paulo',
  __v: 0 }

```
Objeto que não está de acordo com o Schema:

```js
const user = new userModel({
    login:'teste',
    active:'1',
    date_register: '17/02/1999',
    friends:'joão',
    profile_image:10,
    profile_tags:'js mongoose webschool',
    age:'16',
    favorites:[{id:null, data:Date.now()}]
});
```
```shell
{ [ValidationError: users validation failed]
  message: 'users validation failed',
  name: 'ValidationError',
  errors:
   { friends:
      { [CastError: Cast to Array failed for value "joão" at path "friends"]
        message: 'Cast to Array failed for value "joão" at path "friends"',
        name: 'CastError',
        kind: 'Array',
        value: 'joão',
        path: 'friends',
        reason: undefined },
     date_register:
      { [CastError: Cast to Date failed for value "17/02/1999" at path "date_register"]
        message: 'Cast to Date failed for value "17/02/1999" at path "date_register"',
        name: 'CastError',
        kind: 'Date',
        value: '17/02/1999',
        path: 'date_register',
        reason: undefined },
     login:
      { [ValidatorError: Ocorreu um erro documento `login` com valor `teste` do tipo `enum`]
        properties: [Object],
        message: 'Ocorreu um erro documento `login` com valor `teste` do tipo `enum`',
        name: 'ValidatorError',
        kind: 'enum',
        path: 'login',
        value: 'teste' } } }

```

## Cadastre 3 pokemons **de uma só vez**:
```js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// criação do Schema
const _schema = {
    name: String,
    description: String,
    type: String,
    attack: Number,
    defense: Number,
    height: Number,
    crated_at:{type:Date, default: Date.now}
};

const pokemonSchema = new Schema(_schema);

const data = [{name:'Pokemon1', type:'batata', attack:-1, defense:-10, height:6969},
              {name:'Pokemon2', type:'batata', attack:-1, defense:-10, height:6969},
              {name:'Pokemon3', type:'batata', attack:-1, defense:-10, height:6969}];

var Model = mongoose.model('pokemons', pokemonSchema);
data.forEach(function(data){
    var poke = new Model(data);
    poke.save(function(err, data){
        if(err) console.log('Error: ', err);
        console.log('Inseriu: ', data);
    });
});

```

## Busque **todos** os Pokemons com `attack > 50` e `height > 0.5`:
```js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// criação do Schema
const _schema = {
    name: String,
    description: String,
    type: String,
    attack: Number,
    defense: Number,
    height: Number,
    crated_at:{type:Date, default: Date.now}
};

const pokemonSchema = new Schema(_schema);
const PokemonModel = mongoose.model('pokemons', pokemonSchema);
const query = {attack:{$gt:50}, height:{$gt:0.5}};

PokemonModel.find(query, function (err, data) {
  if (err) return console.log('ERRO: ', err);
  return console.log('Buscou:', data);
});

```

```shell
Mongoose default connection connected to mongodb://localhost/exercicio6
Mongoose default connection is open
Buscou: []
```
## Altere, **inserindo**, o Pokemon `Nerdmon` com `attack` igual a 49 e com os valores dos outros campos a sua escolha.
```js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// criação do Schema
const _schema = {
      name:  String,
      description: String,
      type:   String,
      attack:   Number,
      defense:   Number,
      height:   Number
    };
const PokemonSchema = new Schema(_schema);
const Pokemon = mongoose.model('pokemons', PokemonSchema);
const query = {name: /Nerdmon/i}
const mod = {$setOnInsert: {name: 'Nerdmon', description: 'Pokemon badass', type:'nerd', attack:8000, defense:8000, height:100}}
const options = {upsert: true}

Pokemon.update(query, mod, options, function (err, data) {
  if (err) return console.log('ERRO: ', err);
  return console.log('Alterou:', data);
});
```

```shell
paulo@Paulo:~/workshop-be-mean/nodejs/exercicio6$ node app.js
Mongoose default connection connected to mongodb://localhost/exercicio6
Mongoose default connection is open
Alterou: { ok: 1,
  nModified: 0,
  n: 1,
  upserted: [ { index: 0, _id: 56a5790484be28b34911322c } ] }
```

## Remova **todos** os Pokemons com `attack` **acima de 50**.
```js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// criação do Schema
const _schema = {
    name: String,
    description: String,
    type: String,
    attack: Number,
    defense: Number,
    height: Number,
    crated_at:{type:Date, default: Date.now}
};

const pokemonSchema = new Schema(_schema);
const PokemonModel = mongoose.model('pokemons', pokemonSchema);
const query = {attack:{$gt:50}};

PokemonModel.remove(query, function (err, data) {
  if (err) return console.log('ERRO: ', err);
  return console.log('Removeu:', data);
});
```

```shell
paulo@Paulo:~/workshop-be-mean/nodejs/exercicio6$ node app.js
Mongoose default connection connected to mongodb://localhost/exercicio6
Mongoose default connection is open
Removeu: { result: { ok: 1, n: 462 },
  connection:
   EventEmitter {
     domain: null,
     _events:
      { close: [Object],
        error: [Object],
        timeout: [Object],
        parseError: [Object],
        connect: [Function] },
     _eventsCount: 5,
     _maxListeners: undefined,
     options:
      { socketOptions: {},
        auto_reconnect: true,
        host: 'localhost',
        port: 27017,
        cursorFactory: [Object],
        reconnect: true,
        emitError: true,
        size: 5,
        disconnectHandler: [Object],
        bson: {},
        messageHandler: [Function],
        wireProtocolHandler: [Object] },
     id: 2,
     logger: { className: 'Connection' },
     bson: {},
     tag: undefined,
     messageHandler: [Function],
     maxBsonMessageSize: 67108864,
     port: 27017,
     host: 'localhost',
     keepAlive: true,
     keepAliveInitialDelay: 0,
     noDelay: true,
     connectionTimeout: 0,
     socketTimeout: 0,
     destroyed: false,
     domainSocket: false,
     singleBufferSerializtion: true,
     serializationFunction: 'toBinUnified',
     ca: null,
     cert: null,
     key: null,
     passphrase: null,
     ssl: false,
     rejectUnauthorized: false,
     checkServerIdentity: true,
     responseOptions: { promoteLongs: true },
     flushing: false,
     queue: [],
     connection:
      Socket {
        _connecting: false,
        _hadError: false,
        _handle: [Object],
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: true,
        domain: null,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: false,
        destroyed: false,
        bytesRead: 56,
        _bytesDispatched: 169,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        read: [Function],
        _consuming: true },
     writeStream: null,
     buffer: null,
     sizeOfMessage: 0,
     bytesRead: 0,
     stubBuffer: null } }

```


text:
# Node.js - Aula 06 - Exercício

**User:** [Cerezini](https://github.com/Cerezini)

**Autor:** Mateus Cerezini Gomes

## Crie um Schema com cada tipo explicado, inserindo tanto um objeto correto, como um objeto que desencadeie erros de validação padrão, criar especificamente:

* 1.1. para String: `enum`, `match`, `maxlength` e `minlength`
* 1.2.  para Number: `max` e `min`

```js
'use strict';

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const pokemonSchema = new Schema({
  name: {type: String, match: /^(\D)*$/g},
  password: {type: String, minlength: 8},
  description: {type: String, maxlength: 20},
  type: {type: String, enum: ['Water', 'Fire', 'Stone', 'Bug']},
  attack: {type: Number, min: 30},
  defense: {type: Number, max: 70},
  hasSpecial: {type: Boolean, required: true},
  skills: [String],
  created_at: {type: Date, default: Date.now},
  relatedTo: [{type: Schema.Types.ObjectId, ref: 'pokemons'}]
});

const PokemonModel = mongoose.model('pokemons', pokemonSchema);

let poke = new PokemonModel({
  name: 'PotatoMon',
  password: '12345566',
  description: 'A good pokemon',
  type: 'Stone',
  attack: 100,
  defense: 45,
  hasSpecial: true,
  skills: ['throw potatos','potato soup', 'calzone']
});

poke.validate((err, data) => {
  if (err) return console.log(err);
  console.log('Objeto válido');
});
```
Resultado:

```bash
Objeto válido
```

Mudando o objeto `poke`, temos:

```js
let poke = new PokemonModel({
  name: '666PotatoMon',
  password: '1111',
  description: 'A good pokemon that likes to throw potatos in all of its friends, bla bla bla bla',
  type: 'Vegetable',
  attack: 10,
  defense: 100,
  skills: true
});
```
Resultado:

```js
{ [ValidationError: pokemons validation failed]
  message: 'pokemons validation failed',
  name: 'ValidationError',
  errors:
   { hasSpecial:
      { [ValidatorError: Path `hasSpecial` is required.]
        message: 'Path `hasSpecial` is required.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'hasSpecial',
        value: undefined },
     defense:
      { [ValidatorError: Path `defense` (100) is more than maximum allowed value (70).]
        message: 'Path `defense` (100) is more than maximum allowed value (70).',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'max',
        path: 'defense',
        value: 100 },
     attack:
      { [ValidatorError: Path `attack` (10) is less than minimum allowed value (30).]
        message: 'Path `attack` (10) is less than minimum allowed value (30).',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'min',
        path: 'attack',
        value: 10 },
     type:
      { [ValidatorError: `Vegetable` is not a valid enum value for path `type`.]
        message: '`Vegetable` is not a valid enum value for path `type`.',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'enum',
        path: 'type',
        value: 'Vegetable' },
     description:
      { [ValidatorError: Path `description` (`A good pokemon that likes to throw potatos in all of its friends, bla bla bla bla`) is longer than the maximum allowed length (20).]
        message: 'Path `description` (`A good pokemon that likes to throw potatos in all of its friends, bla bla bla bla`) is longer than the maximum allowed length (20).',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'maxlength',
        path: 'description',
        value: 'A good pokemon that likes to throw potatos in all of its friends, bla bla bla bla' },
     password:
      { [ValidatorError: Path `password` (`1111`) is shorter than the minimum allowed length (8).]
        message: 'Path `password` (`1111`) is shorter than the minimum allowed length (8).',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'minlength',
        path: 'password',
        value: '1111' },
     name:
      { [ValidatorError: Path `name` is invalid (666PotatoMon).]
        message: 'Path `name` is invalid (666PotatoMon).',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'regexp',
        path: 'name',
        value: '666PotatoMon' }
  }
}
```

## Cadastre 3 pokemons **de uma só vez**:

A mesma organização de códigos da aula será utilizada, com os arquivos `app.js` e `config.js`. O código a seguir com a criação do `PokemonModel` será omitido nas atividades seguintes porque não será alterado.

```js
'use strict';

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const pokemonSchema = new Schema({
  name: String,
  attack: Number,
  defense: Number,
  hp: Number,
  speed: Number,
  height: String,
  types: [String],
  created: {type: Date, default: Date.now}
});

const PokemonModel = mongoose.model('pokemons', pokemonSchema);

let pokes = [
  new PokemonModel({
    name: 'poke1',
    attack: 50,
    defense: 50,
    hp: 200,
    speed: 30,
    height: '1',
    types: ['electric', 'flyer']
  }),
  new PokemonModel({
    name: 'poke2',
    attack: 100,
    defense: 30,
    hp: 100,
    speed: 50,
    height: '0.5',
    types: ['fire']
  }),
  new PokemonModel({
    name: 'poke3',
    attack: 47,
    defense: 33,
    hp: 50,
    speed: 30,
    height: '3',
    types: ['insect']
  }),
];

PokemonModel.create(pokes, (err, data) => {
  if (err) return console.log('ERROR: ', err);
  console.log('INSERTED: ', data);
});

module.export = PokemonModel;
```

Resultado:

```shell
Mongoose default connection open to mongodb://localhost/be-mean-instagram
Mongoose default connection is open
INSERTED:  [ { types: [ 'electric', 'flyer' ],
    created: Sat Mar 26 2016 21:35:32 GMT-0300 (BRT),
    name: 'poke1',
    attack: 50,
    defense: 50,
    hp: 200,
    speed: 30,
    height: '1',
    _id: 56f72ad41be3caff5458b78e,
    __v: 0 },
  { types: [ 'fire' ],
    created: Sat Mar 26 2016 21:35:32 GMT-0300 (BRT),
    name: 'poke2',
    attack: 100,
    defense: 30,
    hp: 100,
    speed: 50,
    height: '0.5',
    _id: 56f72ad41be3caff5458b78f,
    __v: 0 },
  { types: [ 'insect' ],
    created: Sat Mar 26 2016 21:35:32 GMT-0300 (BRT),
    name: 'poke3',
    attack: 47,
    defense: 33,
    hp: 50,
    speed: 30,
    height: '3',
    _id: 56f72ad41be3caff5458b790,
    __v: 0 } ]
```

## Busque **todos** os Pokemons com `attack > 50` e `height > 0.5`:

```js
let query = {$and: [{attack: {$gt: 50}}, {height: {$gt: 0.5}}]};

PokemonModel.find(query, (err, data) => {
  if (err) return console.log('ERROR: ', err);
  console.log('RETURNED: ', data.length);
});

module.export = PokemonModel;
```

Uma parte do resultado, pois o conjunto resultado contém 423 pokemons:

```shell
[{ types: [ 'ground', 'rock' ],
    created: Sun Nov 03 2013 13:05:42 GMT-0200 (BRST),
    speed: 40,
    name: 'Rhyperior',
    hp: 115,
    height: '24',
    defense: 130,
    attack: 140,
    _id: 564b1dcb25337263280d059a },
  { types: [ 'fighting' ],
    created: Sun Nov 03 2013 13:05:42 GMT-0200 (BRST),
    speed: 45,
    name: 'Conkeldurr',
    hp: 105,
    height: '14',
    defense: 95,
    attack: 140,
    _id: 564b1dcf25337263280d05b9 },
  { types: [ 'flying', 'rock' ],
    created: Sun Nov 03 2013 13:05:42 GMT-0200 (BRST),
    speed: 110,
    name: 'Archeops',
    hp: 75,
    height: '14',
    defense: 65,
    attack: 140,
    _id: 564b1de225337263280d0684 },
  { types: [ 'ground' ],
    created: Sun Nov 03 2013 13:05:41 GMT-0200 (BRST),
    speed: 90,
    name: 'Groudon',
    hp: 100,
    height: '35',
    defense: 140,
    attack: 150,
    _id: 564b1dbf25337263280d052a },
  { types: [ 'flying', 'dragon' ],
    created: Sun Nov 03 2013 13:05:41 GMT-0200 (BRST),
    speed: 95,
    name: 'Rayquaza',
    hp: 105,
    height: '70',
    defense: 90,
    attack: 150,
    _id: 564b1dc625337263280d056f },
  { types: [ 'normal' ],
    created: Sun Nov 03 2013 13:05:41 GMT-0200 (BRST),
    speed: 100,
    name: 'Slaking',
    hp: 150,
    height: '20',
    defense: 100,
    attack: 160,
    _id: 564b1dce25337263280d05b6 },
  { types: [ 'normal' ],
    created: Sun Nov 03 2013 13:05:42 GMT-0200 (BRST),
    speed: 100,
    name: 'Regigigas',
    hp: 110,
    height: '37',
    defense: 110,
    attack: 160,
    _id: 564b1de125337263280d0677 },
  { types: [ 'rock' ],
    created: Sun Nov 03 2013 13:05:42 GMT-0200 (BRST),
    speed: 58,
    name: 'Rampardos',
    hp: 97,
    height: '16',
    defense: 60,
    attack: 165,
    _id: 564b1dc125337263280d0540 }
]

```

## Altere, **inserindo**, o Pokemon `Nerdmon` com `attack` igual a 49 e com os valores dos outros campos a sua escolha.

```js
let query = {name: 'Nerdmon'};
let options = {upsert: true};
let mod = {
  name: 'Nerdmon',
  attack: 49,
  defense: 45,
  hp: 100,
  speed: 30,
  height: '4',
  types: ['nerd', 'electric'],
};

PokemonModel.update(query, mod, options, (err, data) => {
  if (err) return console.log('ERROR: ', err);
  console.log(data);
});

module.export = PokemonModel;
```

Resultado:

```shell
{ ok: 1,
  nModified: 0,
  n: 1,
  upserted: [ { index: 0, _id: 56f746a2387837286197b269 } ] }
```

## Remova **todos** os Pokemons com `attack` **acima de 50**.

```js
PokemonModel.remove({attack: {$gt: 50}}, (err, data) => {
  if (err) return console.log('ERROR: ', err);
  console.log(data);
});
```

Resultado:

```shell
{ result: { ok: 1, n: 463 },
  connection:
   EventEmitter {
     domain: null,
     _events:
      { close: [Object],
        error: [Object],
        timeout: [Object],
        parseError: [Object],
        connect: [Function] },
     _eventsCount: 5,
     _maxListeners: undefined,
     options:
      { socketOptions: {},
        auto_reconnect: true,
        host: 'localhost',
        port: 27017,
        cursorFactory: [Object],
        reconnect: true,
        emitError: true,
        size: 5,
        disconnectHandler: [Object],
        bson: {},
        messageHandler: [Function],
        wireProtocolHandler: {} },
     id: 0,
     logger: { className: 'Connection' },
     bson: {},
     tag: undefined,
     messageHandler: [Function],
     maxBsonMessageSize: 67108864,
     port: 27017,
     host: 'localhost',
     keepAlive: true,
     keepAliveInitialDelay: 0,
     noDelay: true,
     connectionTimeout: 0,
     socketTimeout: 0,
     destroyed: false,
     domainSocket: false,
     singleBufferSerializtion: true,
     serializationFunction: 'toBinUnified',
     ca: null,
     cert: null,
     key: null,
     passphrase: null,
     ssl: false,
     rejectUnauthorized: false,
     checkServerIdentity: true,
     responseOptions: { promoteLongs: true },
     flushing: false,
     queue: [],
     connection:
      Socket {
       _connecting: false,
       _hadError: false,
       _handle: [Object],
       _parent: null,
       _host: 'localhost',
       _readableState: [Object],
       readable: true,
       domain: null,
       _events: [Object],
       _eventsCount: 8,
       _maxListeners: undefined,
       _writableState: [Object],
       writable: true,
       allowHalfOpen: false,
       destroyed: false,
       bytesRead: 250,
       _bytesDispatched: 231,
       _sockname: null,
       _pendingData: null,
       _pendingEncoding: '',
       server: null,
       _server: null,
       _idleNext: null,
       _idlePrev: null,
       _idleTimeout: -1,
       read: [Function],
       _consuming: true },
     writeStream: null,
     hashedName: '29bafad3b32b11dc7ce934204952515ea5984b3c',
     buffer: null,
     sizeOfMessage: 0,
     bytesRead: 0,
     stubBuffer: null } }
```