주소록 - Index, New, Create

소스코드

이 게시물에는 코드작성이 포함되어 있습니다. 소스코드를 받으신 후 진행해 주세요. MEAN Stack/개발 환경 구축에서 설명된 프로그램들(git, npm, atom editor)이 있어야 아래의 명령어들을 실행할 수 있습니다.

이 게시물의 소스코드는 주소록 만들기 / 주소록 - 프로젝트 생성 및 mongoose로 DB 연결에서 이어집니다.

contact-book.git 을 clone 한 적이 있는 경우: 터미널에서 해당 폴더로 이동 후 아래 명령어들을 붙여넣기합니다. 폴더 내 모든 코드가 이 게시물의 코드로 교체됩니다. 이를 원치 않으시면 이 방법을 선택하지 마세요.

git reset --hard
git pull
git reset --hard c1403b9
git reset --soft 1c23437
npm install
atom .

contact-book.git 을 clone 한 적이 없는 경우: 터미널에서 코드를 다운 받을 폴더로 이동한 후 아래 명령어들을 붙여넣기하여 contact-book.git 을 clone 합니다.

git clone https://github.com/a-mean-blogger/contact-book.git
cd contact-book
git reset --hard c1403b9
git reset --soft 1c23437
npm install
atom .

- Github에서 소스코드 보기: https://github.com/a-mean-blogger/contact-book/tree/c1403b902a4568e95acc6301208f3cf67386f88e


7 actions 중 index, new, create을 구현해 봅시다.
이름, 이메일 주소, 전화번호를 받는 form을 만들어서 이 정보를 서버로 전달할 수 있게 하고(new)
서버가 이 정보를 사용해서 DB에 정보를 생성하고(create)
생성된 주소록의 이름 목록을 보여 줍니다(index).

폴더 구조

주황색은 변경된 파일, 녹색은 새로 생성된 파일, 회색은 변화가 없는 파일입니다.

Package 설치

form으로 전송된 data를 사용하기 위해서는 body-parser를 사용해야 합니다.
아래 명령어로 body-parser package를 설치합시다.

$ npm install --save body-parser

코드

// index.js

var express = require("express");
var mongoose = require("mongoose");
var bodyParser = require("body-parser"); // 1
var app = express();

// DB setting ...

// Other settings
app.set("view engine", "ejs");
app.use(express.static(__dirname+"/public"));
app.use(bodyParser.json()); // 2
app.use(bodyParser.urlencoded({extended:true})); // 3

// DB schema // 4
var contactSchema = mongoose.Schema({
 name:{type:String, required:true, unique:true},
 email:{type:String},
 phone:{type:String}
});
var Contact = mongoose.model("contact", contactSchema); //5

// Routes
// Home // 6
app.get("/", function(req, res){
 res.redirect("/contacts");
});
// Contacts - Index // 7
app.get("/contacts", function(req, res){
 Contact.find({}, function(err, contacts){
  if(err) return res.json(err);
  res.render("contacts/index", {contacts:contacts});
 })
});
// Contacts - New // 8
app.get("/contacts/new", function(req, res){
 res.render("contacts/new");
});
// Contacts - create // 9
app.post("/contacts", function(req, res){
 Contact.create(req.body, function(err, contact){
  if(err) return res.json(err);
  res.redirect("/contacts");
 });
});

// Port setting ...

...으로 표시된 부분은 이전과 변화가 없는 부분입니다.
새로 추가된 부분들을 각각 살펴봅시다.

var bodyParser = require("body-parser"); // 1

1. body-parser module를 bodyPaser 변수에 담습니다.

app.use(bodyParser.json()); // 2
app.use(bodyParser.urlencoded({extended:true})); // 3

2 & 3. bodyParser로 stream의 form data를 req.body에 옮겨 담습니다. 2번은 json data를, 3번은 urlencoded data를 분석해서 req.body를 생성합니다.
이 부분이 지금 이해가 안가시면 bodyParser로 이렇게 처리를 해 줘야 form에 입력한 data가 req.body에 object로 생성이 된다는 것만 아셔도 괜찮습니다.

// DB schema // 4
var contactSchema = mongoose.Schema({
 name:{type:String, required:true, unique:true},
 email:{type:String},
 phone:{type:String}
})

4. mongoose.Schema 함수를 사용해서 schema object를 생성합니다.
사용할 Data의 형태를 object로 생성한 다음 mongoose.Schema함수에 넣습니다. contact schema를 살펴보면 name, email, phone의 항목들을 가지고 있으며 새 항목 모두 타입은 String입니다. name은 값이 반드시 입력되어야 하며(required), 값이 중복되면 안됩니다(unique).
이 예제에서는String만 사용했지만, 다양한 type들을 설정할 수 있습니다. 나머지 사용가능한 schema type들은 mongoose 공식사이트에서 확인해 주세요.

var Contact = mongoose.model("contact", contactSchema); //5

5. mongoose.model함수를 사용하여 contact schema의 model을 생성합니다.
mongoose.model함수의 첫번째 parameter는 mongoDB에서 사용될 document의 이름이며, 두번째는 mongoose.Schema 로 생성된 오브젝트입니다. 이로써 mongoDB와 프로그램을 연결해 주는 model이 생성됩니다.
생성된 Contact object는 mongoDB의 contact collection의 model이며 DB에 접근하여 data를 변경할 수 있는 함수들을 가지고 있습니다.

다음으로 route설정입니다.

// Home // 6
app.get("/", function(req, res){
 res.redirect("/contacts");
});

6. "/"에 get 요청이 오는 경우 :
/contacts로redirect합니다.

// Contacts - Index // 7
app.get("/contacts", function(req, res){
 Contact.find({}, function(err, contacts){
  if(err) return res.json(err);
  res.render("contacts/index", {contacts:contacts});
 })
});

7. "/contacts"에 get 요청이 오는 경우 :
에러가 있다면 에러를 json형태로 표시하고, 에러가 없다면 검색 결과를 받아 views/contacts/index.ejs를render합니다.
Contact.find({}, function(err, contacts){ ... })를 살펴봅시다.이 부분을 일반화시키면 모델.find(검색조건callback_함수)로 나타낼 수 있습니다.

모델.find(검색조건callback_함수)를 모델.find검색조건, callback_함수 세부분으로 나누어서 자세히 살펴봅시다.
모델.find 함수는 DB에서 검색조건에 맞는 모델(여기서는 Contact) data를 찾고 callback_함수를 호출하는 함수입니다.
모델.find검색조건은 Object 형태로 전달되는데 빈 Object({})를 전달하는 경우(=검색조건 없음) DB에서 해당 모델의 모든 data를 return합니다.
모델.find의 callback_함수function(에러, 검색결과)의 형태입니다(function(err, contacts){ ... } 부분). 첫번째 parameter인 에러(여기서는 err)는 error가 있는 경우에만 내용이 전달됩니다. 즉 if(err)로 에러가 있는지 없는지를 알 수 있습니다. 두번째 parameter인 검색결과(여기서는 contacts)는 한개 이상일 수 있기 때문에 검색결과는 항상 array이며 심지어 검색 결과가 없는 경우에도 빈 array[]를 전달합니다. 검색결과가 array임을 나타내기 위해 parameter이름으로 contact의 복수형인 contacts를 사용하였습니다.

// Contacts - New // 8
app.get("/contacts/new", function(req, res){
 res.render("contacts/new");
});

8. "/contacts/new"에 get 요청이 오는 경우 :
새로운 주소록을 만드는 form이 있는 views/contacts/new.ejs를render합니다.

// Contacts - create // 9
app.post("/contacts", function(req, res){
 Contact.create(req.body, function(err, contact){
  if(err) return res.json(err);
  res.redirect("/contacts");
 });
});

9. "/contacts"에 post 요청이 오는 경우 :
"/contacts/new"에서 폼을 전달받는 경우입니다.
모델.create은 DB에 data를 생성하는 함수입니다. 첫번째 parameter로 생성할 data의 object(여기서는 req.body)를 받고, 두번째 parameter로 callback 함수를 받습니다.
모델.create 의 callback 함수(여기서function(err, contact){ ... } 부분) 는 첫번째 parameter로 error를 받고 두번째 parameter로 생성된 data를 받습니다. 생성된 data는 항상 하나이므로 parameter이름으로 단수형인 contact를 사용하였습니다.
에러없이 contact data가 생성되면 /contacts로 redirect합니다.

다음으로 view 파일들을 살펴봅시다.

두개의 페이지가 있고 두개의 partial이 있습니다. partial은 여러 페이지들에 중복되는 부분의 코드를 따로 빼 놓은 것입니다.

<!-- views/partials/head.ejs -->

<link rel="stylesheet" href="/css/master.css">
<title>Contact</title>

먼저 head tag에 들어갈 부분입니다.
css와 title을 모든 페이지가 공유하게 하였습니다.

<!-- views/partials/nav.ejs -->

<nav>
 <div>Contact Book</div>
 <ul>
  <li><a href="/contacts">Index</a></li>
  <li><a href="/contacts/new">New</a></li>
 </ul>
</nav>

페이지마다 표시될 menu부분입니다. index와 new view로 이동하는 메뉴를 가지고 있습니다.

<!-- views/contacts/index.ejs -->

<!DOCTYPE html>
<html>
 <head>
  <% include ../partials/head %> <!-- 1 -->
 </head>
 <body>
  <% include ../partials/nav %> <!-- 2 -->

  <div class="contact contact-index">
   <h2>Index</h2>
   <ul>
    <% contacts.forEach(function(contact) { %> <!-- 3 -->
     <li>
      <%= contact.name %>
     </li>
    <% }) %>
   </ul>
  </div>
 </body>
</html>

1&2. <% include %>를 사용해서 외부 ejs(head와 nav)를 가져왔습니다.

3. contacts object에 forEach를 사용해서 코드를 반복해서 표시하고있습니다.

<!-- views/contacts/new.ejs -->

<!DOCTYPE html>
<html>
 <head>
  <% include ../partials/head %>
 </head>
 <body>
  <% include ../partials/nav %>

  <div class="contact contact-new">
   <div class="contact-menu">
    <a href="/contacts">Back</a>
   </div>
   <h2>New</h2>
   <form class="contact-form" action="/contacts" method="post">
    <div>
     <label for="name">Name</label>
     <input type="text" id="name" name="name" value="">
    </div>
    <div>
     <label for="email">Email</label>
     <input type="text" id="email" name="email" value="">
    </div>
    <div>
     <label for="phone">Phone</label>
     <input type="text" id="phone" name="phone" value="">
    </div>
    <div>
     <button type="submit">Submit</button>
    </div>
   </form>
  </div>
 </body>
</html>

새로운 주소를 만드는 form입니다.
form이 submit되면 "/contacts"에 post 를 요청하게 됩니다.

/* public/css/master.css */

.contact h2{
 color: tomato;
}
.contact .contact-form label{
 display: inline-block;
 width: 50px;
}

css 스타일링은 거의 하지 않았습니다. 일단 웹페이지의 기능을 완성한 다음 스타일링을 하도록 하겠습니다.

실행결과

nodemon으로 실행결과를 확인합시다.

$ nodemon

localhost:3000로 접속하면 자동으로 /contacts로 redirect됩니다.

처음 실행하면 생성한 자료가 없으므로 아무런 자료를 보여주지 않습니다. New 링크를 클릭합니다.

주소록을 생성할 수 있는 form이 보입니다. data를 입력하고 submit 버튼을 누릅니다.

/contacts로 redirect되고 입력한 이름이 표시됩니다.

만약 이름을 입력하지 않고 form을 submit하면 에러가 표시됩니다.

동일한 이름을 입력해도 에러가 표시됩니다.

에러의 구조가 다른 것을 볼 수 있는데, 이름이 반드시 필요한 것은 DB로 data를 보내기 전에 mongoose에서 확인해서 error를 낸 것이고, 이름의 중복확인은 DB에서 error를 내는 것이기 때문입니다.

마치며..

다음 강의에서는 나머지 show, edit, update, destroy를 추가하겠습니다.

댓글

오오구 (오구) 2016.10.13
따라하다가 보니 문서상단에 폴더구조 이미지에 나와있는 view/partials/header.ejs 가 view/partials/nev.ejs였네요.. 보고 파일부터 만든 후 코드를 따라가니 계속 오류가나서 좀 헤맸습니다..ㅎㅎ mean은 처음 공부해보는데 따라할 수 록 재밋네요
I
Ian H 2016.10.17
@오오구 (오구),
앗, 그렇네요! 수정하도록 하겠습니다. nodejs 재밌죠 ㅋ 제가 제일 좋아하는 언어입니다.
김남현 2016.10.15
ㅎㅎ, 네이버에서 게시판 강좌 잘 보고 이곳으로 넘어왔습니다. 네이버에서 한번 말씀드린바 있는데(제 네이버 아이디는 sonsory입니다) 다음주 중으로 아주 단순한 형태의 게임이지만, 재미있는 알고리즘이 적용된 숫자게임을 오픈합니다. ㅎㅎ. 오픈하게 되면 사이트주소 남길게요 ㅋㅋ
I
Ian H 2016.10.17
@김남현,
반갑습니다^^ 오. 게임 사이트 만드시는 군요! 기대하겠습니다!
박수진 2017.10.02
res.render("contacts/index", {contacts:contacts}); 이부분에서 두번째 인자로 받는게 어떤건지 알려주실 수 있나요? api를 찾아봐도 이해가 잘 가지않아서요 ㅜㅜ
I
Ian H 2017.10.05
@박수진,
함수(첫번째 인자, 두번째 인자, 세번째 인자, ...) 이므로 res.render("contacts/index", {contacts:contacts})에서 두번째 인자로 받는 것은 {contacts:contacts}입니다.
index.js 코드 7번 부분  말씀하시는거죠? 해당부분 설명이 좀 애매한것 같아서 수정했습니다. 다시 한번 확인해 주시고 그래도 이해가 되지 않으면 다시 질문해 주세요^^
박수진 2017.10.07
@Ian H,
앗 다시보니 제가 질문을 너무 요상하게 썼네요! 두번째 인자{contacts:contacts}이 부분이 어디서 나온 건 지 이해가 안됩니다. 제 생각으론 DB안에 key와 values 개념같긴 한데 맞나요? 저게 무슨역할을 하는거죠?
I
Ian H 2017.10.07
@박수진,
res.render는 ejs파일을 html로 만들어 client(브라우저)로 return하는 함수입니다. 첫번째 인자는 ejs파일의 위치, 두번째 인자는 ejs에서 사용할 수 있는 object입니다. 
{contacts:contacts}에서 첫번째 contacts는 ejs에서 사용할 key이고 두번째 contacts는 Contact.find({}, function(err, contacts){ ... })에서 콜백함수(function(err, contacts){ ... })로 넘겨진 DB에서 읽어온 contact 리스트입니다.
즉 contacts/index.ejs에서 DB에서 읽어온 contact 리스트를 사용하기 위해서 {contacts:contacts}를 넘겨주는 것입니다.
또한 contacts/index.ejs의 <% %> 안의 코드에서 사용되고 있는 contacts가 이때 넘겨받은 contact 리스트를 사용하는 부분입니다.
박수진 2017.10.09
@Ian H,
저같은 초보에게 설명을 너무 잘해주세요 감사합니다!
김성환 2017.10.05
지금까지는 잘 따라서 하고 있는데 events.js에서 에러가 나는데 에러 난 부분을 찾을 수가 없네요ㅠ 힌트 주실 수 있나요?
[nodemon] starting `node index.js` events.js:160       throw er; // Unhandled 'error' event       ^
Error: listen EADDRINUSE :::3000     at Object.exports._errnoException (util.js:1020:11)     at exports._exceptionWithHostPort (util.js:1043:20)     at Server._listen2 (net.js:1262:14)     at listen (net.js:1298:10)     at Server.listen (net.js:1394:5)     at EventEmitter.listen (C:\workspace\contact-book\contact-book\node_modules\express\lib\application.js:618:24)     at Object.<anonymous> (C:\workspace\contact-book\contact-book\index.js:55:5)     at Module._compile (module.js:570:32)     at Object.Module._extensions..js (module.js:579:10)     at Module.load (module.js:487:32)     at tryModuleLoad (module.js:446:12)     at Function.Module._load (module.js:438:3)     at Module.runMain (module.js:604:10)     at run (bootstrap_node.js:383:7)     at startup (bootstrap_node.js:149:9)     at bootstrap_node.js:496:3 [nodemon] app crashed - waiting for file changes before starting...
I
Ian H 2017.10.05
@김성환,
Error: listen EADDRINUSE :::3000 는 해당 port(여기서는 3000이 되겠죠)가 이미 사용중일때 표시되는 에러입니다.
아마 다른 프로그램이 3000을 이미 쓰고 있는 것 같은데 해당 프로그램을 찾아서 꺼주거나 app.listen(3000, ...) 이 부분에 3000이 아닌 다른 숫자를 넣어서 이 프로그램의 실행 port를 바꿔 주시면 됩니다. 물론 웹사이트 접근도 http://localhost:3000 대신 바꾼 port 번호를 넣어주어야 접속됩니다.
d
dombegi 2017.10.17
@김성환,
저도 같은 문제로 골치 아팠습니다. 아마 전에 켰던 node.exe가 계속 돌아가서 그런 것 같습니다.  항상 포트 바꿔주기 귀찮아서 찾아봤더니 (윈도우 기준)
git-bash에 taskkill //f //im node.exe 라는 명령어로 열려있는 모든 node.exe를 끌 수가 있네요. 리눅스용은 stackoverflow에 엄청 많은 결과가 있어서 금방 찾으실 수 있습니다. 도움 되셨으면 좋겠습니다. 
문지상 2018.05.13
Server On! (node:22586) UnhandledPromiseRejectionWarning: Error: URL malformed, cannot be parsed     at module.exports (/Users/crea/Documents/workspace/git/meanstack/contact-book/node_modules/mongodb/lib/url_parser.js:17:21)     at connect (/Users/crea/Documents/workspace/git/meanstack/contact-book/node_modules/mongodb/lib/mongo_client.js:880:3)     at connectOp (/Users/crea/Documents/workspace/git/meanstack/contact-book/node_modules/mongodb/lib/mongo_client.js:269:3)     at executeOperation (/Users/crea/Documents/workspace/git/meanstack/contact-book/node_modules/mongodb/lib/utils.js:420:24)     at MongoClient.connect (/Users/crea/Documents/workspace/git/meanstack/contact-book/node_modules/mongodb/lib/mongo_client.js:260:10)     at Promise (/Users/crea/Documents/workspace/git/meanstack/contact-book/node_modules/mongoose/lib/connection.js:427:12)     at new Promise (<anonymous>)     at NativeConnection.Connection.openUri (/Users/crea/Documents/workspace/git/meanstack/contact-book/node_modules/mongoose/lib/connection.js:424:19)     at Mongoose.connect (/Users/crea/Documents/workspace/git/meanstack/contact-book/node_modules/mongoose/lib/index.js:207:15)     at Object.<anonymous> (/Users/crea/Documents/workspace/git/meanstack/contact-book/index.js:9:10)     at Module._compile (internal/modules/cjs/loader.js:678:30)     at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)     at Module.load (internal/modules/cjs/loader.js:589:32)     at tryModuleLoad (internal/modules/cjs/loader.js:528:12)     at Function.Module._load (internal/modules/cjs/loader.js:520:3)     at Function.Module.runMain (internal/modules/cjs/loader.js:719:10) (node:22586) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id:2) (node:22586) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that 
자꾸 디비를 연결하는데 오류가 나네요ㅠㅠ 환경변수 설정도 했고, $ printenv로 설정도 확인했는데 이러네요. 환경변수를 쓰지 않고 직접 url을 이용해서 연결하면 잘 되는데, 환경변수 설정이 안먹는 듯 싶네요ㅠㅠ 그리고 쉘을 다시 시작하면 처음에는 MONGO_DB라는 변수가 등록이 안되어 있는데, $ source ~/.bash_profile 명령어를 입력해서 등록을 해주어야 환경변수가 적용이 되는 것 같습니다. 아무리 찾아도 이유를 알 수가 없네요 혹시 아신다면 답변 부탁드립니다.
I
Ian H 2018.05.14
@문지상,
구글링해보니 이런 글이 있네요.  https://stackoverflow.com/questions/42392644/mongoose-connection-url-showing-malformed-error
username, password에 특수문자가 있으면 encoding을 해줘야 한다고 합니다. 한번 해보세요^^
K
Kin Dunq 2018.07.13
회사에서 보고 작업중인데  환경이 다른가봐요 많이... 회사에선 pm2로 log도 볼수있었는데ㅎㅎ 집에서 하니까 pm2 로 하면 오류가 뜨네요..
C:\Users\kindunqHome\Desktop\contact>pm2 log [TAILING] Tailing last 15 lines for [all] processes (change the value with --lin es option) C:\Users\kindunqHome\.pm2\pm2.log last 15 lines: PM2        | [2018-07-13T23:47:37.993Z] PM2 log: App [index] with id [0] and pid  [13068], exited with code [1] via signal [SIGINT] PM2        | [2018-07-13T23:47:38.096Z] PM2 log: pid=13068 msg=process killed PM2        | [2018-07-13T23:48:12.800Z] PM2 log: [Watch] Start watching index PM2        | [2018-07-13T23:48:12.817Z] PM2 log: Starting execution sequence in -fork mode- for app name:index id:0 PM2        | [2018-07-13T23:48:12.821Z] PM2 log: App name:index id:0 online PM2        | [2018-07-13T23:48:29.805Z] PM2 error: Change detected on path index .js for app index - restarting PM2        | [2018-07-13T23:48:29.806Z] PM2 log: Stopping app:index id:0 PM2        | [2018-07-13T23:48:29.920Z] PM2 log: App [index] with id [0] and pid  [17388], exited with code [1] via signal [SIGINT] PM2        | [2018-07-13T23:48:30.023Z] PM2 log: pid=17388 msg=process killed PM2        | [2018-07-13T23:48:30.023Z] PM2 log: Starting execution sequence in -fork mode- for app name:index id:0 PM2        | [2018-07-13T23:48:30.027Z] PM2 log: App name:index id:0 online PM2        | [2018-07-13T23:49:08.224Z] PM2 log: [Watch] Stop watching index PM2        | [2018-07-13T23:49:08.225Z] PM2 log: Stopping app:index id:0 PM2        | [2018-07-13T23:49:08.304Z] PM2 log: App [index] with id [0] and pid  [16748], exited with code [1] via signal [SIGINT] PM2        | [2018-07-13T23:49:08.406Z] PM2 log: pid=16748 msg=process killed
C:\Users\kindunqHome\.pm2\logs\index-error.log last 15 lines: 0|index    |     at Mongoose.connect (c:\Users\kindunqHome\Desktop\contact\node_ modules\mongoose\lib\index.js:229:15) 0|index    |     at Object.<anonymous> (c:\Users\kindunqHome\Desktop\contact\ind ex.js:6:10) 0|index    |     at Module._compile (module.js:652:30) 0|index    |     at Object.Module._extensions..js (module.js:663:10) 0|index    |     at Module.load (module.js:565:32) 0|index    |     at tryModuleLoad (module.js:505:12) 0|index    |     at Function.Module._load (module.js:497:3) 0|index    |     at Object.<anonymous> (C:\Users\kindunqHome\AppData\Roaming\npm \node_modules\pm2\lib\ProcessContainerFork.js:75:21) 0|index    |     at Module._compile (module.js:652:30) 0|index    |     at Object.Module._extensions..js (module.js:663:10) 0|index    |     at Module.load (module.js:565:32) 0|index    |     at tryModuleLoad (module.js:505:12) 0|index    |     at Function.Module._load (module.js:497:3) 0|index    |     at Function.Module.runMain (module.js:693:10) 0|index    | (node:13068) DeprecationWarning: current URL string parser is depre cated, and will be removed in a future version. To use the new parser, pass opti on { useNewUrlParser: true } to MongoClient.connect.
C:\Users\kindunqHome\.pm2\logs\index-out.log last 15 lines: 0|index    |     at MongoClient.connect (c:\Users\kindunqHome\Desktop\contact\no de_modules\mongodb\lib\mongo_client.js:168:10) 0|index    |     at Promise (c:\Users\kindunqHome\Desktop\contact\node_modules\m ongoose\lib\connection.js:487:12) 0|index    |     at new Promise (<anonymous>) 0|index    |     at NativeConnection.Connection.openUri (c:\Users\kindunqHome\De sktop\contact\node_modules\mongoose\lib\connection.js:484:19) 0|index    |     at Mongoose.connect (c:\Users\kindunqHome\Desktop\contact\node_ modules\mongoose\lib\index.js:229:15) 0|index    |     at Object.<anonymous> (c:\Users\kindunqHome\Desktop\contact\ind ex.js:7:10) 0|index    |     at Module._compile (module.js:652:30) 0|index    |     at Object.Module._extensions..js (module.js:663:10) 0|index    |     at Module.load (module.js:565:32) 0|index    |     at tryModuleLoad (module.js:505:12) 0|index    |     at Function.Module._load (module.js:497:3) 0|index    |     at Object.<anonymous> (C:\Users\kindunqHome\AppData\Roaming\npm \node_modules\pm2\lib\ProcessContainerFork.js:75:21) 0|index    |   name: 'MongoParseError', 0|index    |   message: 'URI malformed, cannot be parsed', 0|index    |   [Symbol(mongoErrorContextSymbol)]: {} }
이 오류가 뭔지 알수 있을까요? ㅠㅠ
K
Kin Dunq 2018.07.13
nodemon 으로 하면 오류없이 잘됩니다.. ㅎㅎㅎ 그리고 집에서 하니까 아톰 터미널에서 npm 코드가 전혀 안먹히네요 ㅎㅎ 그것도 혹시... 알려주실수 있을까요?
I
Ian H 2018.07.16
@Kin Dunq,
PM2나 아톰 터미널은 제가 몰랐던 것들인데, 이렇게 배우게 되네요 ㅋ 특정한 시스템에서 해당 package들 자체에 에러가 있는 것같은데, 아마 제작자에게 오류를 보고해야 고칠 수 있을 것 같습니다.
김정규 2018.07.14
오늘은 오류가 없네요 ㅎㅎ 근데 궁금한게 routes는 경로를 잡아주는 부분이 있는데  views는 경로를 잡아주는 부분이 없는데 그 부분은 자동으로 잡히는건가요? 약속된 무언가가 있나요?
I
Ian H 2018.07.16
@김정규,
Express가 기본으로 views 폴더에서 view를 찾게 됩니다. app.set('views','./folder/my_view') 를 사용해서 해당 경로를 변경할 수 있습니다
댓글쓰기

이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기

UP