• Как сделать кнопку снова активной после preventDefault()?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    Делать валидацию при каждом нажатии

    doOrderBtn.addEventListener('click', function (el) {
        const phio = document.querySelector('#name')
        const phone = document.querySelector('#phone')
        const address = document.querySelector('#address')
        if (phio.value < 1 && phone.value < 1 && address.value < 1) {
            el.preventDefault()
        }
    });


    PS
    Лучше вешать на submit формы.
    Ответ написан
    Комментировать
  • Как вызывать функцию с теми же аргументами не более одного раза?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    memoization
    это называется «мемоизация» (не от слова «мем», нет : ) Функция запоминает значения аргументов и результат выполнения. Если уже вызывалась с такими аргументами – вернёт «запомненное» значение, не выполняясь ещё раз. Статья на Хабре

    В качестве кэша можно использовать объект или WeakMap, если аргумент – объект.

    distributed lock
    Из вопроса не вполне понятно: в контексте одного выполнения скрипта только один раз, или глобально? Для глобального случая можно использовать какое-то быстрое хранилище, например, Redis, и механизм MutEx ("mutual exclusion" – взаимного исключения), например RedLock.

    На пальцах: вот есть аргумент X. То ли вызвать функцию, то ли параллельно уже другой процесс выполняет и скоро будет готовый результат — вопрос.

    Генерится случайный ключ. Пара (X, ключ) отправляется в асинхронное хранилище, где если нет ещё сохранённого значения под этот X, ячейка запирается (lock) этим ключом. Тут необходима особенность механизма самого хранилища – в Redis это "NX" – записывать только, если уже нет значения. Это гарантирует, при параллельных запросах, что только чьё-то одно случайное значение запишется. Закон джунглей: первый прибежал — наелся!

    Далее надо прочитать записанное значение и получить ключ. Сравнить со своим ранее сгенеренным ключом. Совпали? Значит, это именно мы заперли этот аргумент, и можно выполнить функцию. Не совпали – параллельный процесс выиграл. Просто запросим готовое значение чуть попозже.
    Ответ написан
    1 комментарий
  • Как выводить больше данных с api при нажатии на кнопку?

    @kflipper
    В данном случае api не поддерживает пагинацию. Тебе стоит хранить количество отображенных постов в стейте, а при нажатии на кнопку "показать больше" увеличивать это количество. Как-то так:

    const [product, setProduct] = useState([]);
    const [productsCount, setProductsCount] = useState(8);
    
    useEffect(() => {
    	axios.get(`https://fakestoreapi.com/products?limit=${productsCount}`).then((response) => {
    	  setProduct(response.data)
    	}
    }, [productsCount])
    
    const viewMoreHandle = () => {
    	setProductsCount(prev => prev+5)
    }
    Ответ написан
    Комментировать
  • Как правильно использовать интерцепторы в axios?

    owl1n
    @owl1n
    fullstack developer
    Покажу немного практик, как интерцепторы упрощают жизнь мне, да и многим, в целом.
    Здесь и далее покажу именно использование интерцепторов при работе с авторизацией по JWT (токены).

    1) Подстановка хедера авторизации

    const createSetAuthInterceptor = options => config => {
      if (options.access) {
        config.headers.Authorization = options.access;
      } else {
        delete config.headers.Authorization;
      }
      return config;
    };
    
    const setAuthCb = createSetAuthInterceptor(store.state.auth);
    axios.interceptors.request.use(setAuthCb);


    Здесь мы проверям наличие доступа из стора, а точнее, наличие токена. Далее, подставляем, либо удаляем заголовок.

    2) Следующая практика, это обновление токена (то, о чем вы спросили в комментарии, при окончании сессии и т.д.)

    let refreshTokenPromise;
    
    const createUpdateAuthInterceptor = (store, http) => async error => {
      const message = get(error, 'response.data.message');
      if (!['Token expired', 'Invalid token'].includes(message)) {
        return Promise.reject(error);
      }
    
      if (!refreshTokenPromise) {
        refreshTokenPromise = store.dispatch('refreshToken');
      }
    
      await refreshTokenPromise;
      refreshTokenPromise = null;
    
      return http(error.config);
    };
    
    const updateAuthCb = createUpdateAuthInterceptor(store, axios);
    axios.interceptors.response.use(null, updateAuthCb);


    Здесь мы можем видеть, что при каждом ответе проверяем наличие ошибок и если ошибка соответствует ошибке с токеном, то отправляем обновлять токен и далее снова отправляем тот же самый запрос, который к нам вернулся с ошибкой. Тут грамотно будет проверять не само сообщение об ошибке, а код ответа (401 и т.д.), но тут используется такое решение уже из за специфики бэка.

    В этом же решение, вместо обновления токена, можно отправлять юзера авторизовываться самому, на страницу авторизации. Для этого, конечно же, стоит передавать не экземпляр store, а экземляр роутера, чтобы редиректить юзера. Надеюсь, помог и хоть как то наглядно показал способы применения :)
    Ответ написан
    1 комментарий
  • Что за проект сделать на фронте, что показывает, что можно идти на собеседование?

    Без портфолио на github смысла нет. На джуна можно сделать, например:
    1. микро клон инстаграма (основной функционал).
    2. микро клон авито (основной функционал).

    Естественно самый основной функционал на главной странице, чтобы показать навыки адаптивной верстки, разделения системы на компоненты, умение делать коммиты, собирать все на webpack. Естественно фронт не должен быть идеальным, но должен быть приемлемого качества, но верстка должна быть правильной.

    Лично мое мнение, исходя из того, что иначе просто толку 0 будет.
    Ответ написан
    7 комментариев