• Как в 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
       }
    }
    Ответ написан
    Комментировать
  • Как сделать проверку 2 json в fetch .then()?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Заюзать Promise.all.
    До есть делаете не const result = fetch().then(), а типа так:
    const result = fetch();
    const result2 = fetch();
    
    Promise.all([result, result2]).then(values => {
      console.log(values);
    });
    Ответ написан
    Комментировать
  • Как записать значение из input?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Мой вариант:
    Вот подправленный вариант: https://jsfiddle.net/Fi1osof/Lf2at5go/1/
    Ответ написан
    Комментировать
  • Как сделать несколько событий?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Нельзя так перечислить несколько событий. Смотрите доку: https://developer.mozilla.org/ru/docs/Web/API/Even...
    type
    Чувствительная к регистру строка, представляющая тип прослушиваемого события.

    То есть только один тип события.
    Но можно несложный цикл организовать. Так работает.
    ['click', 'mouseover']. map(type => document.querySelector('.o').addEventListener(type, (event)=> {
      console.log(event.type, document.querySelector('.o').textContent);
    }))
    Ответ написан
  • Почему выполняется запрос при повторной отрисовке компонентов?

    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 и т.п.. Лучше смотрите документацию по используемым вами компонентам как добавить свои собственные обработчики ошибок.
    Ответ написан
  • Почему задержка для async функции срабатывает только один раз?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    async function delay(n) {
      setTimeout( () => (alert(n)), 2000)
    }

    В данном случае async не имеет никакого смысла, потому что функция setTimeout не является асинхронной. Это обычная функция с двумя параметрами (один из них callback).

    Надо так:
    function delay(n) {
      return new Promise((resolve) => {
        setTimeout( () => resolve(alert(n)), 2000)
      });
    }


    Но это просто переделан ваш вариант. В целом такой подход, как у вас, не практикуется. Перепишите свой код.
    Ответ написан
    Комментировать
  • Как исправить ошибку preloader js?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    Вероятней всего вот причина:
    setTimeout () - это уже выполнение. А надо именно функцию передавать.
    Попробуйте обернуть в () => {....}
    То есть
    window.addEventListener('load', () => {
       setTimeout(function () {
          preload.innerHTML = '<audio src="sounds/startsound.mp3" controls autoplay></audio>';
          var audio = document.querySelector("audio");
          audio.volume = 0.3;
          preload.style.display = 'none';
        }, 1000)
    });


    То есть, после того, как документ загрузится, у вас вызовится функция, которая запустит setTimeout(...)
    Ответ написан
    Комментировать
  • Почему выбивает ошибку когда запускаю build?

    Fi1osof
    @Fi1osof
    JS fullstack developer
    У вас четкая ошибка:
    ERROR in Error: C:\Users\Aspire 3\Desktop\error-handling\src.ts\index.html:94
    var canvas = document.getElementById('canvas');
    ^
    ReferenceError: document is not defined


    document (если нет никаких иммитаторов) на стороне сервера отсутствует. Условно у вас сборка выполняется для SSR (Server-side rendering). И вот он пытается выполнить обращение к document, а его нету.
    Оберните в проверку, например так:

    if(global.document){
       ....
    }
    Ответ написан
    Комментировать