Ответы пользователя по тегу GraphQL
  • Как в React написать mutation и query на сервер GraphQL?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Нина, во-первых, у вас неправильно написана мутация, чисто синтаксически.
    У вас написано
    const mutation = `
    mutation createUser($firstName: String,$secondName: String, $email: String,$password:String){
      createUser(firstName: $firstName,secondName:$secondName,email:$email, password:$password){ 
       signup(   
          firstName
          secondName
          email
          password   
          )
      }
    }`;


    а должно быть
    const mutation = `
    mutation createUser(
      $firstName: String
      $secondName: String
      $email: String
      $password: String
    ) {
      signup(
        firstName: $firstName
        secondName: $secondName
        email: $email
        password: $password
      )
    }
    `;


    То есть у вас, во-первых, лишняя обертка получилась, во-вторых, вы не передали в запрос указанные параметры.

    Но даже в этом случае у вас не пройдет запрос, так как в схеме у вас некоторые параметры указаны как обязательные, а вы в своем запросе их не указали обязательными. Вот смотрите схему:
    type Mutation {
      signup(
        firstName: String!
        secondName: String!
        email: String!
        password: String!
      ): String
      // ...
    }

    У вас здесь все параметры обязательные, то есть ваш запрос должен выглядеть так:
    const mutation = `
    mutation createUser(
      $firstName: String!
      $secondName: String!
      $email: String!
      $password: String!
    ) {
      signup(
        firstName: $firstName
        secondName: $secondName
        email: $email
        password: $password
      )
    }
    `;


    В целом же, судя по тому, что у вас ошибка возникает в .mjs - файлах, она возникает не на стороне фронта, а уже на стороне АПИ-сервера, так что сам механизм у вас вроде как реализован. Но сама тема слишком объемная, чтобы в одном комменте можно было бы ее раскрыть. Попробуйте посмотреть вот это видео: https://www.youtube.com/watch?v=69e-omuXdIw
    Оно объемное, но зато раскрывает все уровни реализации GraphQL-API.
    Ответ написан
    2 комментария
  • Как использовать 2 useQuery в одном файле?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Вероятный ответ.
    Ответ написан
    Комментировать
  • Как через graphql узнать путь к файлу?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Но зачем это делать через граф? Обычно на сайтах используют типа react-router-dom, и с его же помощью определяют какая сейчас страница и активной делать ссылку или нет.
    В нем специально есть NavLink. Он сам становится активным, когда совпадает. Остается только класс активной ссылки указать. https://reactrouter.com/web/api/NavLink
    Ответ написан
    Комментировать
  • Почему при попытке обновить state из useEffect он не обновляется?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Никита, вы зря засунули setTabsFields внутрь цикла map. setTabsFields - это синхронная функция. При каждом выполнении цикла map и вызове setTabsFields у вас let obj = {...tabsFields} не является новым объектом с актуальным состоянием tabsFields. В вашем случае это всегда новый объект, но с одними и теми же данными, которые были в tabsFields на момент выполнения цикла.
    Сделайте примерно так:
    useEffect(() => {
    
            // const obj = {...tabsFields}
            // Сдесь скорее всего всегда пустой объект начальный должен быть, иначе в нем могут остаться уже неактуальные данные.
            const obj = {}
    
            if (data !== undefined) {
                // перебираю массив контактных лиц
                data.org.contactPersons.map(i => {
                    const ID = nanoid(8) // использую либу nanoid для генерации ID
    
                    obj[i._id + '~' + ID + '^name'] = i.name 
                    i.phone.map((j, idx) => {
                        obj[i._id + '~' + ID + '^phone-' + idx] = j
                    })
    
                    i.eMail.map((j, idx) => {
                        obj[i._id + '~' + ID + '^eMail-' + idx] = j
                    })
                })
            }
    
             // Устанавливаем конечный набор полей в стейт
             setTabsFields(obj)
    
        }, [data])
    Ответ написан
    Комментировать
  • Как предотвратить ошибку graphQL и выполнить мутацию по scalar type в схеме?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    У вас ArbitraryObject - scalar, а не объект с описанными полями. На это вам и ругается граф - нельзя в запросе перечислять какие-либо поля для него. То есть нельзя написать запрос типа
    query {
       my_query {
         scalar_field {
            ...someFields
         }
       }
    }

    Можно только
    query {
       my_query {
         scalar_field
       }
    }
    Ответ написан
    Комментировать
  • Почему выполняется запрос при повторной отрисовке компонентов?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Вряд ли здесь бага графа.

    Скорее всего у вас где-то логическая ошибка. Почему так говорю? Потому что вы в data?.login != null используете != (не строгое сравнение). Старайтесь максимально использовать нестрогое сравнение, иначе вы привыкаете к неточностям. Если вы в данном случае хотите явно сравнивать нестрого, тогда хотя бы пишите if(!data?.login). Хотя это тоже не строгое сравнение, но так более принято.

    Во-вторых, у вас
    if (data?.login != null) {
    onAuth(data.login)
    }
    выполняется при каждом рендеринге. Так как у вас в этот момент логин не пустой, у вас каждый раз срабатывает метод onAuth. Идите посмотрите что в нем.

    В-третьих, посмотрите конфиг созданного аполло-клиента, может вы в нем прописали по-умолчанию fetchPolicy: 'network-only' или типа того.
    Ответ написан
  • Как как через Apollo (GraphQl) загрузить несколько файлов?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Ваш представленный здесь запрос рассчитан на передачу только одного файла. С таким запросом несколько файлов передать вы никак не сможете.
    Вот запрос на передачу нескольких файлов за один запрос:
    {
                mutation: gql`
                  mutation Feedback(
                    $message: String!
                    $files: [Upload!]!
                  ) {
                    Feedback(
                      message: $message
                      files: $files
                    ) {
                      request
                    }
                  }
                `,
                variables: {
                  message: dataMessage,
                  files: dataFiles,
                },
    }


    Если он у вас не работает, значит проблема на стороне сервера (Возможно вы там прописали обработку одного передаваемого файла).
    Вот пример обработки нескольких загруженных файлов: https://github.com/prisma-cms/upload-module/blob/m... (хотя в сети наверняка сможете найти более компактный вариант).

    P.S. >> В доке рекомендуют тип указывать в квадратных скобках

    Дело не в доке, а в синтаксисе GraphQL. В квадратных скобках - это массив. Если хотите передавать массив файлов, то обязательно тип должен быть объявлен в квадратных скобках, то есть массив.
    Ответ написан
    2 комментария
  • Метод resolve в GraphQL какие принимает параметры и что они делают?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    parent - это родительский объект.
    В вашем случае если вы запрашивается Movie {director {...}}
    то в резолвере director parent будет объект Movie, из которого вы получаете director.

    P.S. и вы ответы без реакции не оставляйте, а то мотивация отвечать снижается.
    Ответ написан
  • GraphiQl в ответе data, все поля null. Почему?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Вероятней всего вы массив возвращаете вместо объекта, то есть [...] вместо {...}. Попробуйте так:
    const [value] = Directors.filter((arr)=>(arr.id === args.id));
    return value;


    А лучше вообще так:
    return Directors.find((arr)=>(arr.id === args.id));


    Просто filter возвращает отфильтрованный массив, а не найденный в нем элемент.

    То есть в ответ ему приходит объект (а массив - это тоже объект), но у него нет свойств name и id.
    Ответ написан
  • Почему data всегда пустые, если я получаю ошибку?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Они у вас не все пустые.
    false !== null. То есть userStatus у вас отработал и вернул значение false.
    А вот при обработке viewer судя по всему и возникла ошибка. В errors информация какая именно ошибка, и да, в таком случае возвращает null. Разберетесь с ошибкой - будет возвращать что надо.

    >> но клиентская часть data всегда undefined
    У вас скорее всего apollo используется? Или типа того. Они не возвращают ничего, если прилетела ошибка, так устроены. Соответственно вам тогда надо для них прописать свой собственный обработчик ошибок.
    Ответ написан
    4 комментария
  • Как использовать один и тот же объект но с разными свойствами в разных компонентах?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Для полноты картины надо было еще схему вашего компонента приложить.

    Если в вашей схеме что-то типа такого:
    type Metric {
      id: Int!
      something: String
    }

    и хотите, чтобы он мог корректно возвращать entities: 50, то самое правильное это добавить это свойство в саму модель.

    type Metric {
      id: Int!
      """ Боевая переменная """
      something: String
    
      """ Для тестов """
      entities: Int
    }


    То есть у вас и та и другая переменная в схеме есть, передавать можно любое свойство, при этом поля не обязательные, так что если не будет получено, то ничего страшного.

    Это по сути единственный наиболее удобный путь для этого.

    Если у вас ситуация сложнее (в боевом режиме значительно больше полей и вы не хотите все поля перечислять), то для малозначительных моделей вы и вовсе можете задать тип JSON.
    Если вы используете Apollo-Server, вот их официальная инструкция: https://www.apollographql.com/docs/graphql-tools/s...
    Тогда у вас объект может вообще любой набор валидных свойств иметь. Но не советую с этим увлекаться, это часто приводит к хаосу.
    Ответ написан
    4 комментария
  • Сколько способов загрузки файлов с использованием API GraphQL есть?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Я не скажу сколько именно есть способов загружать файлы в граф, но как минимум один распространенный есть. Но я так же оговорюсь сразу, что не знаю как это работает или нет с AWS, потому что я им не пользуюсь, а пишу код на своих серверах.

    1. Полю, которое должно содержать загружаемый файл, задаем тип Upload.
    Скорее всего при сборке схемы граф заругается, что такой тип ему не известен, просто где-нибудь пораньше объявим этот тип:
    scalar Upload
    Никаких обработчиков дополнительных специально под этот тип не надо прописывать, это только уже в самих резолверах.

    2. В резолвере, которым обрабатывается этот запрос, пишем приемку и и обработку файла. Вот для при мера мой код, принимающий загружаемый файл: https://github.com/prisma-cms/upload-module/blob/b...

    3. С фронта отправка файлов выполняется через доступ к стандартному File-API из объекта event поля input.
    https://github.com/prisma-cms/uploader/blob/7d8240...

    К слову, по запросу "graphql aws upload file" гугл выдает очень много ответов, и вот это видео все наглядно показывает: https://www.youtube.com/watch?v=Ue3Tn0ZzfdY (правда на англ).
    Ответ написан
  • Как добавить строку в массив ошибок?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Вам не надо пытаться сломать то, что работает. Если заложено так, чтобы был массив ошибок, значит должен быть массив ошибок.
    А на стороне клиента, где вы хотите обеспечить собственный обработчик ошибок, можете просто получать первый объект из массива ошибок и его использовать.
    .catch(([error]) => {
            console.error(error, error.message);
          });


    Еще раз повторюсь, ломать это точно не надо. Это целая экосистема, включая всякие там GraphiQL, apollo-client, apollo-error-link и т.п.. Лучше смотрите документацию по используемым вами компонентам как добавить свои собственные обработчики ошибок.
    Ответ написан
  • Как правильно написать Graphql запрос в моем случае?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Само по себе наличие метода еще не дает вам права вызывать его через GraphQL-запросы. Что и как можно запрашивать - отвечает схема. Собственно, на скринах схему видно. filter - это именованный объект. В запросах параметры передаются в таком виде:
    query {
      someQuery(
        argName: argValue,
        ...
      ){
         ....fields
      }
    }


    Нельзя вызывать как функцию типа filter(...args)

    В вашем случае типа так:
    query {
      advertisementsByFiltersearch(
        filter: {
          name: "Name"
          usefilter: true
          lowerprice: 300
        }
      ){
         ....fields
      }
    }
    Ответ написан
    Комментировать
  • Prisma.io - как получить количество записей в модели?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Запаздалый ответ, но все же.
    Когда вы деплоите схему, на каждый тип формируется три типа запроса (речь про Query):
    object - уникальный объект
    objects - список объектов
    objectsConnection - список объектов с данными количества и т.п.

    В вашем случаем это будет

    query {
      gamesConnection{
        aggregate{
          count
        }
        edges{
          node{
            id
          }
        }
      }
    }


    Ответ будет типа:
    {
      "data": {
        "gamesConnection": {
          "aggregate": {
            "count": 0
          },
          "edges": []
        }
      }
    }


    Соответственно edges не обязательно указывать, если вам надо получить только кол-во записей.

    Важный момент: в более ранних версиях призмы (типа 1.15) aggregate возвращало общее кол-во найденных объектов. То есть, к примеру, если вы напишите такой запрос:
    query {
      gamesConnection (
        where: {
          name_contains: "Test"
        }
        first: 2
      ){
        aggregate{
          count
        }
        edges{
          node{
            id
          }
        }
      }
    }


    Вы могли получить ответ типа
    {
      "data": {
        "gamesConnection": {
          "aggregate": {
            "count": 15
          },
          "edges": [{id:"dsfdsf"}, {"id":"sdfsdgds}]
        }
      }
    }


    То есть Получено 2 записи (потому что first: 2 указано), но всего найдено 15 записей, содержащих в названии "Test".

    Так вот, в более поздних версиях (и сейчас), aggregate возвращает именно кол-во полученных записей, то есть в нашем случае вернет не 15, а 2 (потому что получил 2 записи), даже если там всего 15 записей имеется. Я считаю, что такое изменение абсолютно бессмысленно (потому что на стороне клиента я и сам могу посчитать сколько объектов получил), и даже тикет им отправлял, но они сказали, что это фича, а не бага.
    По этой причине надо писать запросы типа так:
    query games (
      $where: GameWhereInput
      $first: Int
    ){
      gamesConnection (
        where: $where
      ){
        aggregate{
          count
        }
      }
      
      games (
        where: $where
        first: $first
      ){
        id
        name
      }
    }


    То есть тут сразу два запроса с передачей условия и лимита как параметры.
    В первый (подсчет) передается только условие. А во второй (непосредственно список объектов) уже условие и лимит (и другие параметры, если надо). Ответ будет типа
    {
      "data": {
        "gamesConnection": {
          "aggregate": {
            "count": 0
          }
        },
        "games": []
      }
    }
    Ответ написан
    Комментировать