Ответы пользователя по тегу Node.js
  • Какая разница в инструментах webpack?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    webpack-dev-server - средство для удобной разработки ваших одностраничных приложений от webpack (то есть, из "коробки")

    webpack-dev-middleware - собственно, middleware, который добавляет возможности вашему другому серверу (в случае тэга вопросов - написанному на node.js и фреймворке express). Что добавляет? Ну хотя бы, возможность hot-reload'a..

    Что и где использовать разницы нет. Как вам удобнее так и делайте. Либо просто webpack-dev-server, либо какой-то ваш "усложенный" сервер написанный на node.js + middleware webpack-dev-server. Под middlewar'ом можно понимать некий "усилитель", как уже было написано, например: усиливай мой "сервер" на "hot-reload"
    Ответ написан
    Комментировать
  • Как правильно настроить webpack-dev-server?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    1) либо не создан index.html на одном уровне с конфигом webpack
    2) либо нет роута по '/'

    p.s. + покажите console браузера, может там еще какая ошибка по делу будет.
    Ответ написан
  • Совокупность каких фреймворков backend + frontend является самым быстрым в контексте получения данных клиентом?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Предполагаю, что стоит не четкая задача + прокрастинация (в смысле: выбирать на чем делать, приятнее/труднее/совесть_меньше_пристает/и тд чем делать. Так как делать - это головняк, трудности (реальные) и все такое).

    По поводу задачи:
    = На backend работа с базой данных (CRUD) [окей, ±тянет на задачу]
    = На фронтенде node.js с Angular 2 Universal. [а это уже выбор конкретных технологий, задача то какая? Задача скорее всего, выглядит как: сделать SPA (одностраничное приложение)]

    Далее вы хорошо расписываете пункты. Поэтому частично прокомментирую:
    Работать с базой данных (CRUD) через REST запросы, при этом добавление/удаление/изменение данных доступно только залогиненному через ГУГЛ, ВК или Твиттер пользователю в роли администратора — не ясно

    Все очень просто, например, используете токен. Не лучший (зато простой), но все же пример с которого можно начать.

    Придется ли использовать в таком случае backend на каком-нибудь php фреймворке типа Laravel или yii2?

    Для "изоморфного" вам нужно научиться отдавать контент страницы в html. На чем делать - не важно.

    Можно ли обойтись только фреймворками для node.js для таких вещей как CRUD + кэширование REST ответов от БД + кэширование изображений + сжатие страниц по типу gzip?

    Не специалист, но думаю почти на все пункты "да".

    Являются ли фреймворки на node.js более медленными по сравнению с php фреймворком на nginx в контексте запросов к бд и обработки данных?

    Скорее да, но это какие-то узкие места, которые вряд ли сразу у вас всплывут. Опять же, тут не спец.

    Резюмирую: вам нужно начать делать. Берете инструменты для backend и пишите API, потом берете "что-угодно" на frontend для взаимодействия с этим API.

    p.s. Если задача запустить какую-то идею - вообще не переживайте за технологический стэк, просто берите и делайте хоть на том же sails, вообще не факт, что вам нужен изоморфный одностраничник...

    p.p.s. Совокупность каких фреймворков backend + frontend является самым быстрым в контексте получения данных клиентом? - однозначного ответа нет, и вряд ли будет. Даже если придут люди с картинками, на которых нарисованы циферки тестов.
    Ответ написан
  • Начальный шаблон express'a (что? где? куда?)?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Ищите поиском по статье, которую вы привели в примере:
    Здесь будут жить все ваши макеты и файлы представления Jade.

    То есть, ваши шаблоны нужно класть в директорию views. В статье используется jade, поэтому посмотрите как работает этот шаблонизатор. Шаблон главной страницы, доступной по урлу mysite.com
    demo-app/views/index.jade

    Далее, как запустить, снова ищем поиском в статье:
    Это код, который позволяет вам запускать npm start для приложения.

    => для запуска, нужно выполнить в терминале:
    node ./bin/www

    или можно
    npm start
    Ответ написан
    2 комментария
  • Что за сопостовления в express?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Это стадартный роутинг. Вы переходите по урлу, например mysite.com/abe или mysite.com/abcde , что сервер будет вам отдавать? Правильно, то что вы указали внутри "сопоставимого" роута, в случае этого примера, это ваш последний кейс:
    app.get('/ab(cd)?e', function(req, res) {
    res.send('ab(cd)?e'); // здесь может быть что-нибудь, например: покажи страницу с такой-то картинкой
    });
    Ответ написан
    1 комментарий
  • Как найти учителя JS и Node.js?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В тему про codementor.io (ссылка, почему-то неправильно вставляется)
    https://www.codementor.io/experts?q=nodejs&lang=russian
    Ответ написан
    Комментировать
  • Nodejs/express + ES6 рекомендации?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    По первому пункту, ссылка от Антона в помощь.

    По второму вопросу: вы на node.js будете делать бэкэнд. Который будет являться API сервером, не более. Здесь придется поизучать что такое REST API. Следовательно, если вы будете писать фронтенд на react/redux, то кладете его в другую директорию, там уже свой package.json и т.д., так как ваш фронтенд и бэкэнд - это две разные вещи.
    Ответ написан
    Комментировать
  • Как реализовать авторизацию пользователя на стеке React Redux Node?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Пригодится jwt. (гугл)

    В общих словах: вам нужно выдать юзеру токен. С этим токеном юзер будет выполнять запросы к вашим защищенным методам api (вы можете оставить какие-то методы "без токена").

    Node.js часть
    Пример роута на логин (сделано не лучшим образом, в плане коллбэков, но что нашлось под рукой...):

    auth.js
    ...
    const v4 = require('node-uuid').v4
    const jwt = require('jsonwebtoken')
    ...
    router.post('/signin', (req, res, next) => {
    
      // валидация, например... 
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        // поиск юзера в базе, сравнение хэша и прочие необходимые операции
        ...
       // допустим все ок, нужно ответить токеном
      // генерируем необходимые опции и сам токен
    
            const payload = {
              _id: user._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              // отвечаем токеном, для будущих запросов с клиента
              return res.json({ data: token })
            })
         ...
    })
    
    module.exports = router;


    Пример защищенного роута (метода, который требует токен):
    ...
    const jwt = require('jsonwebtoken')
    const Poll = require('../models/poll')
    ...
    
    const requireToken = (req,res,next) => {
      const token = req.headers['x-api-key']
      const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
    
      jwt.verify(token, secret, (err, decoded) => {
        if (err) {
          return res.status(401).json({ error: err.message })
        }
        req.params.userId = decoded._id
        next()
      })
    }
    ...
    
    // обратите внимание на requireToken - функция вызывается при каждом обращении к роуту
    // то есть при каждом PUT запросе по адресу (например: PUT api/v1/products/1238914)
    // будет вызываться requireToken
    
    router.put('/:id', requireToken, (req, res, next) => {
      const { productId } = req.body
      const userId = req.params.userId
    
      Poll.findById(req.params.id)
        .populate({ path: 'products' })
        .exec((err, poll) => {
            // ... необходимые действия в базе, в процессе успешного зачтения голоса...
        }
    })


    Клиентское приложение:

    Типичный ActionCreator (в качестве библиотеки для запросов можно взять bluebird, isomorphic-fetch, да хоть нативный xhr)
    actions/LoginActions.js

    export function login(data) {
      return dispatch => {
        dispatch({ type: LOGIN_REQUEST })
    
        // request в данном случае - https://github.com/KyleAMathews/superagent-bluebird-promise
        return request.post(`${API_ROOT_V1}/auth/signin`)
          .send(data)
          .then(res => {
            if (!res.ok) {
              dispatch({ type: LOGIN_FAILURE })
            } else {
              dispatch({
                type: LOGIN_SUCCESS,
                data: res.body.data,
              })
              //сохранение токена в localStorage
              localStorage.setItem('cks_token', res.body.data)
            }
          }, err => {
            dispatch({ type: LOGIN_FAILURE })
          })
      }
    }


    Пример голосования с токеном (выше, в node.js части был метод апи, а это PUT запрос с клиента)

    export function vote(productId, voteId) {
      return dispatch => {
        dispatch({ type: POLL_VOTE_REQUEST })
    
        return request.put(`${API_ROOT_V1}/api/v1/vote/${voteId}`)
          .set('X-API-Key', localStorage.getItem('cks_token')) // установка ТОКЕНА в заголовок 'X-API-Key'
          .send({ productId })
          .then(res => {
            if (!res.ok) {
              dispatch({ type: POLL_VOTE_FAILURE })
            } else {
              dispatch({
                type: POLL_VOTE_SUCCESS,
                data: normalize(res.body.data, schema.poll),
              })
            }
          }, err => {
            dispatch({ type: POLL_VOTE_FAILURE })
          })
      }
    }


    Надеюсь код формы с кнопкой "голосовать" не трубется.
    ====

    Все это можно организовать удобнее, например, выставлять токен всем запросам автоматически (речь про клиентскую часть):
    import fetch from 'isomorphic-fetch'
    ...
    const defaultHeaders = {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    }
    
    function buildHeaders() {
      const authToken = localStorage.getItem('TOKEN')
      return { ...defaultHeaders, Authorization: authToken }
    }
    ...
    export function httpPost(url, data) {
      const body = JSON.stringify(data)
    
      return fetch(url, {
        method: 'post',
        headers: buildHeaders(),
        body: body,
      })
      .then(... код оработки запроса ...)
    }


    ===

    Проверить наличие токена, можно с в роутере, с помощью хука на onEnter.

    root.js
    ...
    <Provider store={store}>
          <Router history={routerHistory}>
            {configRoutes(store)} // Роуты создаются функцией, чтобы можно было использовать внутри нее store.getState()
          </Router>
        </Provider>
    ...


    routes.js
    export default function configRoutes(store) {
      function _ensureAuthenticated(nextState, replace, callback) {
        const { dispatch } = store
        const { session } = store.getState()
        const { currentUser } = session
        let nextUrl
    
        if (!currentUser && localStorage.getItem('cks.token')) {
          dispatch(getCurrentAccount())
        } else if (!localStorage.getItem('cks.token')) {
          replace('/signin')
        }
        callback()
      }
    
      return (
        <Route path='/' component={App}>
          <Route path='/signin' component={SigninContainer} />
          <Route path='/signup' component={SignupContainer} />
    
          <Route path='/locked' component={AuthenticatedContainer} onEnter={_ensureAuthenticated}>
            <Route component={LockedArea}>
              <Route path='/locked/a' component={A} />
              <Route path='/locked/b/:id' component={B} />
              <Route path='/locked/c' component={C} />
            </Route>
          </Route>
        </Route>
      )


    Остается только создать AuthenticatedContainer в котором проверять: есть ли currentUser (в рамках этого примера) и если нет - возвращать false. А если есть - this.props.children (в которых будут дальнейшие роуты..)
    ===

    Итого:
    1) у вас есть API написанное на node.js.
    2) У этого API есть защищенные методы, которые проверяют наличия токена в http-запросе. Токен выдается при запросе на логин. Само собой, операция логина (то есть POST запрос на your-api/login) не требует токена.
    3) После удачного логина, вы получаете в ответе на свой запрос токен (это уже внутри клиентского кода, и если мы говорим о redux - то внутри асинхронного вызова в actions)
    4) Сохраняете токен (например, в localStorage)
    5) Во все необходимые http-запросы устанавливаете заголовок с токеном
    Ответ написан
    15 комментариев
  • Как найти преподавателя по Node.js?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Как уже писал не раз тут на тостере - начните с codementor.io (поиском node.js и russian). Там ставка выше, но я думаю сможете договориться.

    P.S. в целом же, менторов на русском языке найти очень не просто.
    Ответ написан
  • Как запустить meteor.js?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Можно запускать команду через screen
    То есть, команда screen как будто бы открывает виртуальную вкладку, в ней запускаете meteor, затем выходите из скрина (обычно это ctrl + A,D ) и у вас "сессия" в той виртуальной вкладке остается висеть. Чтобы снова к ней присоединиться, нужно написать screen -R. Ну или просто почитайте подробнее про screen.
    Ответ написан
    1 комментарий
  • Динамический сайт на nodejs, как сделать?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Грубо говоря, вы используете php в том числе и в качестве шаблонизатора, так? Значит и на node смотрите в эту же сторну, например if условие в jade.
    Ответ написан
    1 комментарий
  • Как и где найти преподавателя?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    1)codementor.io (там выбираете тэги: нужные вам технологии и ru/rus/russian например).
    2) фрилансим - создаете задачу.
    3) здесь на тостере у интересных вам пользователей (в нужных тэгах опять же) смотрите контакты - пишете в личку.
    4) просите кого-то из друзей в IT компаниях попросить кого-то из их друзей научить.

    Ваши вопросы:
    1) javascript (очевидно). Написать "смену контента" на кнопки можно без использования библиотек, или с ними.
    2)
    какой самый быстрый и оптимальный способ отправки данных на сервер
    : обычный запрос (POST), веб-сокеты... вряд ли что-то еще.

    а также как создать такой сервер и базу и мини API для приёма и записи данных

    вопрос слишком общий. Что на сервере? (наверняка MySQL база) На чем писать API будете? и т.д.
    Ответ написан
    Комментировать
  • Актуальны ли Каторовские уроки по NodeJs?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    А какие требования были? Если: видео, русский язык - то лучше курса я не знаю.
    Если же требования: видео/статьи, язык: русский/английский, то думаю да, после изучения первой части курса, лучше поискать боевой пример поновее. Но! Много не потеряете, если посмотрите вторую часть и поделаете на старой версии.
    Ответ написан
    Комментировать
  • Как реализовать отправку отрендерившегося сообщения (React) чата в другой html-класс?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Использовать flux/redux
    Использовать "события" (хоть custom Event , хоть EventEmitter (после заголовка Глобальная система событий), хоть jquery events)
    Ответ написан
    Комментировать
  • Как работает роутинг в связке angular2 + express?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    А как вы вообще планируете использовать express ? MEAN стэк подразумевает, что ваш бэкэнд - это только REST API, если не ошибаюсь. Следовательно - у вас все запросы на youhost.com/api/, например, идут в express и там он разруливает роуты, а все остальные запросы идут в клиентское приложение и там разруливает ангуляр.
    Ответ написан
    Комментировать
  • Какие данные необходимо записывать в jwt (node.js + mongo)?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Логин класть в токен не нужно. В токене не должно быть "личной информации", а вот ObjectId уже можно. Это не подходит "под личную", так как по 5821d94dbb021a1360582da3 нельзя узнать что-то о пользователе, если у вас не своровали базу (могу ошибаться).

    Приведу на всякий случай полный код роута с выдачей токена, если вам не особо пригодится, так может кто поругает, так как в бэкэнде не силен. Код не на промисах, а на коллбэках (как в древние времена). Это плохо. С помощью промисов будет "более плоский" и удобный в поддержке код.

    const express = require('express')
    const router = express.Router()
    const User = require('../models/user')
    const v4 = require('node-uuid').v4
    const jwt = require('jsonwebtoken')
    
    router.post('/signup', (req, res, next) => {
    
      req.check('email', 'Please enter a valid email').len(1).isEmail()
      req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)
    
      const errors = req.validationErrors()
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        User.hashPassword(req.body.password, (err, passwordHash) => {
          if (err) {
            return res.status(400).json({ error: err.message })
          }
    
          const user = new User({
            name: req.body.name,
            nickname: req.body.nickname,
            email: req.body.email,
            password: req.body.password,
          })
    
          user.passwordHash = passwordHash
          user.save((err, item) => {
            if (err) {
              return res.status(400).json({ error: err.message })
            }
            const payload = {
              _id: item._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              return res.json({ data: token })
            })
          })
        })
      }
    })
    
    router.post('/signin', (req, res, next) => {
    
      req.check('email', 'Please enter a valid email').len(1).isEmail()
      req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)
    
      const errors = req.validationErrors()
      const password = req.body.password
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        User.findOne({ email: req.body.email }, (err, user) => {
          if (err) {
            return res.status(400).json({ error: err.message })
          }
          if (!user) {
            return res.status(400).json({ error: 'User not found' })
          }
          User.comparePasswordAndHash(password, user.passwordHash, (err, areEqual) => {
            if (err) {
              return res.status(400).json({ error: err.message })
            }
            if (!areEqual) {
              return res.status(400).json({ error: 'Wrong password' })
            }
            const payload = {
              _id: user._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              return res.json({ data: token })
            })
          })
        })
      }
    })
    
    module.exports = router;


    В дальнейшем, кусочек payload:
    const payload = {
              _id: item._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }

    можно "декодировать" прямо на клиенте, что очень удобно.
    Ответ написан
    Комментировать
  • Как правильно установить nvm на os x?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Мне помогло полное удаление NVM и node.js. Далее порядок: установить NVM, после этого установить node.js через NVM.

    Пост про удаление node.js stackoverflow.com/a/11178106/1916578
    Ответ написан
    1 комментарий
  • Как подключить handlebars в .hbs шаблон?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    А вы используете express? Если да, то вам нужен express-handlebars
    Так же нужно установить в качестве "шаблонизатора" - handlebars.
    app.engine('handlebars', exphbs({defaultLayout: 'main'}));
    app.set('view engine', 'hbs'); //в офф.доке используют расширение handlebars
    Ответ написан
  • Как правильно организовать авторизацию веб-сервиса на Express?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Как на счет jwt ?

    За! Удобно, нравится.

    Вкратце - шлете стандартные регистрационные данные, сервер выдает вам токен. Далее токен добавляете в заголовки запросов.

    В прицнипе, в гугле инфы хватает по вопросу. Сам сайт посмотрите (jwt.io), оттуда ссылка на пакет для node

    Скопирую сюда куски кода из своего api сервера, но скажу сразу - в node я не очень силен, если будут замечания от знающих - только рад. Так же angular кода не приведу, потому что клиентский код у меня на react.

    Здесь в файле используются callbacks, возможно есть варианты получше. В других роутах приложения я где-то через async поигрался, где-то через promise.

    Мой роутер auth

    const express = require('express')
    const router = express.Router()
    const User = require('../models/user')
    const v4 = require('node-uuid').v4
    const jwt = require('jsonwebtoken')
    
    router.post('/signup', (req, res, next) => {
    
      req.check('email', 'Please enter a valid email').len(1).isEmail()
      req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)
    
      const errors = req.validationErrors()
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        User.hashPassword(req.body.password, (err, passwordHash) => {
          if (err) {
            return res.status(400).json({ error: err.message })
          }
    
          const user = new User({
            name: req.body.name,
            nickname: req.body.nickname,
            email: req.body.email,
            password: req.body.password,
          })
    
          user.passwordHash = passwordHash
          user.save((err, item) => {
            if (err) {
              return res.status(400).json({ error: err.message })
            }
            const payload = {
              _id: item._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              return res.json({ data: token })
            })
          })
        })
      }
    })
    
    router.post('/signin', (req, res, next) => {
    
      req.check('email', 'Please enter a valid email').len(1).isEmail()
      req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)
    
      const errors = req.validationErrors()
      const password = req.body.password
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        User.findOne({ email: req.body.email }, (err, user) => {
          if (err) {
            return res.status(400).json({ error: err.message })
          }
          if (!user) {
            return res.status(400).json({ error: 'User not found' })
          }
          User.comparePasswordAndHash(password, user.passwordHash, (err, areEqual) => {
            if (err) {
              return res.status(400).json({ error: err.message })
            }
            if (!areEqual) {
              return res.status(400).json({ error: 'Wrong password' })
            }
            const payload = {
              _id: user._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              return res.json({ data: token })
            })
          })
        })
      }
    })
    
    module.exports = router;


    Модель user

    const mongoose = require('mongoose')
    const bcrypt = require('bcrypt')
    const Schema = mongoose.Schema
    let bcrypt_cost = 12
    
    const userSchema = new Schema({
      name: { type: String, required: true },
      email: { type: String, required: true },
      passwordHash: String,
    })
    
    userSchema.statics.hashPassword = (passwordRaw, cb) => {
      if (process.env.NODE_ENV === 'test') {
        bcrypt_cost = 1
      }
      bcrypt.hash(passwordRaw, bcrypt_cost, cb)
    }
    
    userSchema.statics.comparePasswordAndHash = (password, passwordHash, cb) => {
      bcrypt.compare(password, passwordHash, cb)
    }
    
    const User = mongoose.model('User', userSchema)
    
    module.exports = User


    В коде роутера есть AUTHO_CLIENT - так как я изначально брал реализацию от AUTH0, кстати, может понравится? У них удобно все... Но для себя в целях обучения переписал на свою. (какая-то ссылка у них про angular cookies vs token)

    Мне нравится, что некоторую информацию я могу взять прямо из токена (например, уровень доступа - в моем примере - poll)
    Ответ написан
  • Из-за чего возникает ошибка ReferenceError: Schema is not defined?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Потому что у вас не определена переменная Schema
    добавьте в начало файла: var Schema = mongoose.Schema

    p.s. ну и на всякий случай, давайте разберемся.
    ReferenceError: Schema is not defined

    в переводе - Schema - не определено. И действительно, если вы посмотрите в свой код, то у вас нигде нет записи в стиле var Schema = ..., следовательно вы не можете использовать эту переменную, так как ее просто не существует. Она никак не requir'ится в ваш файл, вы никак ее не определяете...
    Ответ написан
    Комментировать