Страница компании
Выполняется
Проект: Пивная карта
Планируемый запуск: | 29.05.2021 | Дата начала: | 29.05.2021 | Планируемое завершение: | 02.06.2021 | Дата завершения: |
Проект | Задача | Статус | Дата постановки | Начало | Конец | Кто создал |
---|---|---|---|---|---|---|
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 22.06.2021 05:08:58 | 22.06.2021 05:26:12 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 08.06.2021 05:54:31 | 08.06.2021 06:13:37 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 04.06.2021 05:38:18 | 04.06.2021 06:18:58 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 04.06.2021 03:59:36 | 04.06.2021 05:25:22 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 03.06.2021 05:52:19 | 03.06.2021 06:50:21 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 03.06.2021 04:31:21 | 03.06.2021 05:44:13 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 03.06.2021 03:42:03 | 03.06.2021 04:15:34 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 31.05.2021 06:11:04 | 31.05.2021 06:23:53 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 31.05.2021 05:17:32 | 31.05.2021 05:58:08 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 31.05.2021 04:49:49 | 31.05.2021 05:05:05 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 29.05.2021 09:00:56 | 29.05.2021 09:19:26 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 29.05.2021 09:00:49 | 29.05.2021 09:00:53 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 29.05.2021 07:08:54 | 29.05.2021 08:02:44 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 29.05.2021 06:15:24 | 29.05.2021 06:22:09 | |
Пивная карта | Страница компании | Выполняется | 29.05.2021 04:54:21 | 29.05.2021 04:58:06 | 29.05.2021 05:46:50 |
Николай, привет!
Похоже я так и не понял принцип роутинга в next
Дима, привет!
Давай все-таки чуть по-другому: что именно тебе не понятно. Не пересказывать же мне все сначала и до конца? Делись мыслями. Вон как Олег вопросы свои задает.
Тоже верно)
Не совсем понимаю логику работы роутинга.
У нас есть в бд куча компаний, у которых есть uri, вида place/2027/buckbier_haus
Завел папку company, в ней - [uri].tsx с export { default } from 'src/pages/Companies/Company'
Файл src/pages/Companies/Company/index.tsx
Вроде как должно отдать что-то, а отдает 404
Где ошибка?
Не, похоже надо перебирать урлу:
заводить папку place, убирать id - он кажется лишним и делатьб динамический урл типа [url_name]
Сюда добавил url_name, но видимо надо перегенерировать типы.
Использовал команду yarn generate: types , посыпались ошибки. Делал в папке /pivkarta.ru-2
Я затянул текущую версию. Как надо было действовать?
Николай, привет!
Вот такая ошибка при yarn generate:types
dima@dima-Lenovo-ideapad-720-15IKB:~/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2$ yarn generate:types
yarn run v1.22.5
$ cross-env NODE_PATH=. ts-node -P tsconfig.server.json src/modules/gql/cli/generateTypes/run
✔ Parse configuration
✔ Generate outputs
✔ Parse configuration
✔ Generate outputs
✔ Parse configuration
❯ Generate outputs
❯ Generate to types (using EXPERIMENTAL preset "near-operation-file")
✔ Load GraphQL schemas
✔ Load GraphQL documents
✖ Generate
→ Fragment "city_" is set on non-existing type "City"!
Found 1 error
✖ types
Error: Fragment "city_" is set on non-existing type "City"!
at /home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/fragment-resolver.js:48:27
at Array.reduce (<anonymous>)
at buildFragmentRegistry (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/fragment-resolver.js:42:32)
at buildFragmentResolver (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/fragment-resolver.js:75:30)
at resolveDocumentImports (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/resolve-document-imports.js:11:30)
at Object.buildGeneratesSection (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/index.js:27:25)
at /home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/graphql-codegen-cli/src/codegen.js:215:64
at Task.task (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/graphql-codegen-cli/src/codegen.js:27:17)
Error: Fragment "city_" is set on non-existing type "City"!
at /home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/fragment-resolver.js:48:27
at Array.reduce (<anonymous>)
at buildFragmentRegistry (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/fragment-resolver.js:42:32)
at buildFragmentResolver (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/fragment-resolver.js:75:30)
at resolveDocumentImports (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/resolve-document-imports.js:11:30)
at Object.buildGeneratesSection (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/presets/near-operation-file/src/index.js:27:25)
at /home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/graphql-codegen-cli/src/codegen.js:215:64
at Task.task (/home/dima/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2/dist/graphql-codegen-cli/src/codegen.js:27:17)
Во время генерации схемы произошла ошибка ListrError Something went wrong
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
dima@dima-Lenovo-ideapad-720-15IKB:~/docker/docker-pivkarta/prisma-cms/pivkarta.ru-2$
Понял сам:
--------------------
Выполнение команд внутри контейнера.
Иногда надо выполнить какую-нибудь команду в самом контейнере, например yarn generate:types.
Для этого нам надо зайти в нужный нам контейнер. Откроем еще один терминал и выполним в директории проекта docker-compose ps. Найдем в списке наш контейнер и его имя (скорее всего будет docker-pivkarta_pivkarta.ru-2_1).
Выполняем docker exec -it docker-pivkarta_pivkarta.ru-2_1 bash
Если ОК, то мы оказываемся внутри контейнера, то есть как бы в другом компьютере. Только следует учитывать, что конкретно этот образ не на базе ubuntu создан, а alpine-linux. Некоторые командыы могут отличаться (например, не apt install, а apk add). И вот, когда мы внутри, выполняем yarn generate:types.
--------------------
>> Не, похоже надо перебирать урлу:
заводить папку place, убирать id - он кажется лишним и делатьб динамический урл типа [url_name]
Да, с роутингом у тебя точно не так все. Особенно сложно оценивать, когда не говоришь под какой именно УРЛ пытаешься создать правило.
Напиши какой УРЛ пытаешься запросить и напиши какое правило пытаешься для него создать (путь к файлу от корня проекта).
>> Выполняем docker exec -it docker-pivkarta_pivkarta.ru-2_1 bash
Да, так мы заходим в контейнер и выполняем в нем что хотим. А есть еще чуть другой вариант, без захода в контейнер:
exec -it docker-pivkarta_pivkarta.ru-2_1 yarn generate:types
То есть после docker exec -it container_name пишем выполняемую программу с параметрами. Тогда докер выполняет эту команду внутри указанного контейнера и выводит результат.
>> Есть боковой вопрос: https://github.com/Pivkarta/pivkarta.ru-2/blob/master/src/modules/gql/generated/company.ts
Сюда добавил url_name, но видимо надо перегенерировать типы.
В generated ничего писать ручками не нужно. На это и generated. И там в каждом файле предупреждение прописано
Если ты хочешь, чтобы там что-то появилось, надо править в исходных graphql-файлах, то есть сами запросы.
---------------------------- Таки появилось)))))
По урлу: думаю, что имеет смысл place/[url_name]
Как думаешь?
>> По урлу: думаю, что имеет смысл place/[url_name]
Как думаешь?
Как думаешь? - не очень корректный вопрос. Правильней добавить и посмотреть результат, и в зависимости от него двигаться дальше. Но все же сразу скажу, что это не правильно в данном случае, так как [url_name] - это только один сегмент УРЛа. Если хочешь любую вложенность, то надо троеточие добавлять. Таким образом для тебя это будет place/[...url_name]
Тогда все УРЛы в разделе place/... будут попадать туда. Смотри примеры и разъяснения в оффдоке https://nextjs.org/docs/routing/dynamic-routes
Спасибо, изучаю
Николай, роутинг сделал: https://github.com/Pivkarta/pivkarta.ru-2/commit/5ef0983f98145e4e5223de8109e38f5d02118f8b
Теперь надо по url_name вытащить данные компании из бд. Что можно взять за образец?
Вот я писал: Особенно сложно оценивать, когда не говоришь под какой именно УРЛ пытаешься создать правило.
Напиши какой УРЛ пытаешься запросить и напиши какое правило пытаешься для него создать (путь к файлу от корня проекта).
Какой УРЛ ты пытаешься запросить и какое правило прописал?
http://localhost:3100/place/pivovarennaya_kompaniya_ooo_dok-n-dan_piv_ko
Правило: <Link href={'/place/' + company.url_name || '/'}>
Правило, имелось ввиду типа /place/[url_name].tsx
Для УРЛа /place/pivovarennaya_kompaniya_ooo_dok-n-dan_piv_ko такое сгодится. Но у тебя же на сайте адреса типа /place/10192/glavpivmag-v-pyatnickom, то есть твое такое правило не подходит. А если есть адреса типа /place/pivovarennaya_kompaniya_ooo_dok-n-dan_piv_ko, то надо еще одно правило создавать.
Ну а за основу можешь взять эту страницу: https://github.com/Pivkarta/pivkarta.ru-2/blob/327007dc245ac4c38d18a94565e1b20b797b3c1d/src/pages/Comments/Comment/index.tsx
Но более комплексный и универсальный пример вот этот: https://github.com/gorodskie-bani-ru/nextjs/blob/56861d0e5556a4d4de1e582a8ee8048b4fe5c903/src/pages/Resource/index.tsx
В нем перехватываются все страницы и в зависимости от типа возвращенного по АПИ объекта выводится та или иная вьюха. Правило для нее вот это используется: /[...path].tsx
Вообще-то это: /place/10192/glavpivmag-v-pyatnickom у нас напрямую забито в бд - параметр uri
Тогда я вообще какую-то ерунду придумал - надо брать uri и пользовать.
Изучаю примеры.
uri брать сильно надежней.
Николай, привет!
Сделал роутинг по [uri] - коммит
Получаю uri на странице копании из урл - там слэши убраны, то есть жду place/10782/amorales_brewery, а прилетает place10782amorales_brewery
Здесь place = статика
10782 = place_id
amorales_brewery = url_name
То есть если вытащить place_id, то видимо по нему можно длобыть данные о компании через https://github.com/Pivkarta/pivkarta.ru-2/blob/master/src/gql/Query/Company.graphql
Но не очень понятно, как этот place_id выковарить из полученного uri, если без разделителей.
Можешь подсказать?
Дима, привет!
>> Получаю uri на странице копании из урл - там слэши убраны, то есть жду place/10782/amorales_brewery, а прилетает place10782amorales_brewery
Это все потому что ты не учишь матчасть. Всю подобную отладку надо выводить в console.log(), потому что там ты увидишь результат без лишних преобразований. А ты что делаешь? Выводишь в реакт. Это хорошо хоть там массив и ты хоть что-то увидел. А был бы объект, получил бы и вовсе ошибку.
Так вот, реакт массивы как есть не выводит, тем более string[]. В данном случае он выполнил перед выводом uri.join(""). Смотри оффдоку https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/join
Там как раз есть пример
У тебя просто все строчные элементы массива в одну строку без разделителя собрались и все. Пусть это будет тебе горьким уроком.
И еще: я свое для примера дал. В твоем случае правильней прописать правило /places/[...uri], потому как сейчас у тебя туда вообще все будет залетать, для чего роутинг не прописан, включая страницы пива.
Пожалуйста!
>>В твоем случае правильней прописать правило /places/[...uri], потому как сейчас у тебя туда вообще все будет залетать, для чего роутинг не прописан, включая страницы пива.
Тогда повится новое колено - /places/
а на действующем сайте его нет. Так - то не важно, но мало ли
>> Тогда повится новое колено - /places/
а на действующем сайте его нет. Так - то не важно, но мало ли
Ну да, я спутал, не /places/, а /place/
А place/ в uri "пришит". Я поэтому и хотел разобрать uri на части, чтобы place/ вывести в папку, а place_id и url_name использовать для формирования урлы
Дима, вот у тебя страницы пива имеют вид /beer/1552/singha, то есть каждая страница пива начинается с /beer/
Если ты оставишь маску /[...uri],то у тебя туда будут попадать и /place/...., и /beer/..., и все остальное (для чего не определены более явно правила роутинга). По-твоему это нормальный вариант? Я считаю, что нет. То есть ты должен завести отдельно /place/[...uri] и /beer/[...uri], чтобы четко разделить правила для заведений и пива. Такие моменты ты должен продумывать и учитывать на стадии планирования. Нельзя просто так сесть и делать что-то только чтобы делать. Сначала надо подумать, прокрутить в голове различные варианты, и только потом делать наиболее оптимальный, если считаешь, что он возможен. В твоем случае ты сначала это должен учитывать, а только потом задаться вопросом "Но у меня в router.query.uri не то, что мне нужно. Что делать?". Вот тут уже ищешь другие варианты реализации, а именно посмотри внимательней объект console.log(router), есть ли там более подходящая информация для тебя?
Да, вот эта часть очень сложная, и как я и предупреждал, она не на один день. Но ее надо изучить и изучить подробно, даже если займет неделю и больше, потому что когда ты разрабатываешь веб-проект, ты всегда сталкиваешься с задачами разбора УРЛ. Более того, всегда прорабатывай адреса типа /place/10782/amorales_brewery?test=foo#hash, потому что если ты смотришь только /place/10782/amorales_brewery, ты потом можешь поймать логические ошибки, когда в УРЛ у тебя появятся дополнительные параметры, которых ты не ожидаешь.
Вот когда научишься разбирать нормально УРЛ, подробней изучишь обхект Location, столкнешься с тем, что его нет на стороне сервера, когда поймешь почему я вот здесь использую urijs, когда сам осмысленно используешь подобное у себя, вот тогда только можно переходить дальше к получению данных с сервера и рендереру конечной страницы.
Развернуто, спасибо. Изучаю дальше
----
Эта конструкция /place/[...uri] НЕ ДУБЛИРУЕТ place/ из uri (это я напамять записал)
Николай, привет! Сделал запрос со страницы компании. Можешь посмотреть на предмет ошибок и более оптимальных решений?
Дима, привет!
В который раз задаю вопрос: ты разве в IDE своей не видишь ошибки? У тебя и тесты на гитхабе ошибку выдают
То есть у тебя ожидается number | null | undefined, а ты пытаешься скормить number | string. Строку нельзя сюда. То есть что надо сделать? Проверить на тип и привести к нужному типу. А главное: надо не молчать про это, а спрашивать, что за ошибка и как с ней бороться. А если пытался сам бороться и не победил, значит надо показывать что пытался делать и что не получается.
Опять-таки, нельзя игнорировать такие ошибки. Мало того, что в отсутствие переменной у тебя parseFloat вернет NaN, так еще и если переменной router.query.uri не будет вовсе, то router.query.uri[0] вызовет эксепшн.
Ну а по самому исполнению: выключи в браузере JS и обнови страницу. Обрати внимание, что в странице с сервера нет данных компании. Это потому что аполло-хуки синхронные, а реакт - асинхронный. Тебе надо прописать получение данных компании асинхронно еще на стороне сервера, чтобы в коде страницы был кеш компании и данные ее были при рендеринге получены асинхронно из кеша. Тогда у тебя данные компании будут сразу, а на стороне фронта не будетвыполняться лишнего АПИ-запроса для получения их.
Вообще ты вот здесь кашу нагородил:
Зачем тебе вот эта проверка? placeid && typeof placeid === 'number' ? placeid : ''
Во-первых, у тебя на вход функции прописано (placeid: number), то есть на вход у тебя всегда number будет заходить (если и не будет, то только из-за ошибки где-то на стороне и там как раз будет ТС-ошибка). Тип уже задан, тебе не надо его проверять.
Во-вторых, в случае Иначе ты возвращаешь '', то есть пустую строку. В итоге ты number сам же превращаешь в number | string. И вот зачем?
>>В который раз задаю вопрос: ты разве в IDE своей не видишь ошибки? У тебя и тесты на гитхабе ошибку выдают
Ошибку с place_id вижу и понимаю, но оставил, так как сталкиваюсь не первый раз, а как правильно решите - не знаю. У нас в бд есть параметры с "_", на что и ругается IDE. А как к place_id обратиться правильно?
По остальному - спасибо, изучаю)
>> У нас в бд есть параметры с "_", на что и ругается IDE. А как к place_id обратиться правильно?
Я тебе не про эслинт CamelCase. У тебя на то игнор добавлен. А именно про Type error: Type 'string | number' is not assignable to type 'Maybe<number> | undefined'. Ты внимательней смотри ошибки.
То есть это типовая ошибка, а не стилистическая.
Николай, привет!
А вот с ассинхронным выполнением вопрос:
смотрю пример, читаю учебник, но как использовать - не складывается.
Дима, привет!
Сорри за долгий ответ, я в дороге.
Хуки нельзя вызывать асинхронно, они выполняются как есть. Смотри комментарий выше, я писал что надо задействовать. Суть в том, чтобы выполнить не хук, а именно аполло-запрос асинхронно, в специальном методе. Тогда этот результат попадает в кеш аполло и в основном рендерере даныне берутся из кеша, а потом выводятся сразу же при первом рендерере.
Спасибо!Разбираюсь