• Проблема с Access-Control-Expose-Headers?

    search
    @search
    мама говорит что я особенный
    `Access-Control-Allow-Origin` - это хедер ответа от сервера, а не хедер запроса. Он должен быть выставлен на сервере. Если вы не знаете с какого домена будет приходить запрос, то нужно выставлять `Access-Control-Allow-Origin: *`

    Эту проблему невозможно решить на клиенте, но ангуляр предоставляет сделать прокси на время разработки (тут хотел вставить ссылку на документацию, но тупой тостер запрещает использовать ссылки) . Этот прокси не будет работать на проде/стейджинге. Так что проблему всё равно прийдётся решать путём установки нужных хедеров на серваке.

    Если что, фраза "No 'Access-Control-Allow-Origin' header is present on the requested resource." на русский язык переводится как "Хедер 'Access-Control-Allow-Origin' не представлен на запрашиваемом ресурсе"
    Ответ написан
    Комментировать
  • Где взять реальные примеры кода использования ооп в веб-сервисах?

    search
    @search
    мама говорит что я особенный
    Книга Приёмы объектно-ориентированного проектирования. П... предоставляет весьма популярные практики использования ООП. Написана в 1994 году. По сей день считается "маст рид" для программиста.
    Ответ написан
    Комментировать
  • Ошибка http запроса при подключении SSL почему?

    search
    @search
    мама говорит что я особенный
    Это называется CORS https://developer.mozilla.org/ru/docs/Web/HTTP/CORS

    Это можно поправить только на стороне сервера, передав вот такой хедер: Access-Control-Allow-Origin: domain.ru

    Этим хедером вы разрешите сайтам на domain.ru совершать запросы к вашему серверу. Если сервер не передает такой хедер, то запросы режет сам браузер и на стороне клиента это не исправить никак.

    Если вам заранее не известно на каком домене будет находиться клиент, то можно передавать Access-Control-Allow-Origin: *
    Ответ написан
    Комментировать
  • Как преодолеть неуверенность при разработке джуниору?

    search
    @search
    мама говорит что я особенный
    С наставником проще достичь результата за относительно короткий срок. Человек выше верно написал "Путь к "более-менее сносный мидл" - это как минимум 3 года упорного тяжёлого труда.", и это верно. Но опыт показывает что человек, просидевший 3 года в джунах без наставника имеет риск нахватать вредных привычек и превратиться в "закостенелого джуна".

    Не всегда приятно получать критику. Особенно если ты долго что-то делал беззаветно и с высунутым языком. Но есть способ смягчить удар. Это найти толкового человека в коллективе и объявить его своим сенсеем. Можно даже так и называть его - "сенсей", он не обидится. И советоваться с ним по любым вопросам. Сенсей будет себя вести сдержаннее по отношению к вам, ведь он сенсей. А вам будет проще получать критику, ведь критика - это то что вы ожидаете получить от сенсея.
    Ответ написан
    Комментировать
  • Почему не работает long polling?

    search
    @search
    мама говорит что я особенный
    Это происходит потому что PHP лочит сессию на каждом запросе. Это ставит в очередь другие ajax запросы. Для того чтоб освободить залоченную сессию можно выполнить

    $request->session()->save();

    где-нибудь перед while.

    $request->session()->save() в недрах фреймворка вызывает session_write_close() что освобождает сессию и даёт дорогу другим запросам.

    Вся эта колбасня с локами сессионных файлов нужна для того чтоб несколько запросов подряд не запоганили сессию. Если захотите что-нибудь записать в сессию после вызова $request->session()->save(), то, возможно прийдётся заново открывать сессию. Я хз, сделает ли ларавел это за вас или нет. На вашем месте советую убедиться самостоятельно, чтоб потом с бубном не плясать.
    Ответ написан
    Комментировать
  • Как сделать принудительную загрузку страниц сайта фоном?

    search
    @search
    мама говорит что я особенный
    Вот эта либа подгружает нужную страницу при наведении мыши на ссылку instantclick.io

    На мой взгляд это гораздо гуманнее чем подгружать прям все страницы. И экологичнее тоже.
    Ответ написан
    Комментировать
  • Как вырезать prop types из production?

    search
    @search
    мама говорит что я особенный
    prop-types должен устанавливаться в dependencies потому что он подключается в исполняемых файлах. Это не важно что он отключен в продакшене.

    Собственно, документация тоже говорит устанавливать prop-types в dependencies https://github.com/facebook/prop-types#installation

    УПД

    Немного проясню разницу между devDependencies и dependencies. В devDependencies подключается инфраструктура проекта, например, библиотеки для юнит тестирования, билдеры, всевозможные вебпаки.

    Если какая-то библиотека импортится в исполняемых файлах проекта (читай, тех файлах, которые в каком-то переработанном виде попадают к пользователю), то она подключается только в dependencies.
    Ответ написан
    2 комментария
  • Как изменить new Promise на util.promisify?

    search
    @search
    мама говорит что я особенный
    Как-то так:

    Location.getLocationByUrlSlugWithPromise = util.promisify(Location.getLocationByUrlSlug.bind(Location));
    Ответ написан
    Комментировать
  • Могу ли я настроить angular 7 приложение на запуск не в корневой папке?

    search
    @search
    мама говорит что я особенный
    ng build --prod --base-href /app/ должен помочь
    Ответ написан
    Комментировать
  • Какой сейчас самый современный способ получить массив из объекта?

    search
    @search
    мама говорит что я особенный
    Самый модни-мжвячни-современни способ - это так:

    Object.values(yourObject).flat()

    Естественно, flat не работает в микрософтовских браузерах, поэтому понадобится Бабел или полифил.
    Ответ написан
    Комментировать
  • Как вернуть данные или сделать еще два запроса в Rx.js в зависимости от результата первого запроса?

    search
    @search
    мама говорит что я особенный
    Это делается через switchMap:

    this.httpClient.get('/check-email').pipe(
      switchMap(emailResult => {
        if (emailResult !== exists) {
          return of(dataForNonExistingEmail);
        }
        
        return forkJoin(
          this.httpClient.get('/user-data1'),
          this.httpClient.get('/user-data2')
        );
      })
    )
    Ответ написан
    3 комментария
  • Как правильно передавать данные через сервис Angular?

    search
    @search
    мама говорит что я особенный
    Для вашего случая существует лучшая практика: так называемые умные и глупые компоненты: https://medium.com/@dan_abramov/smart-and-dumb-com... (это оригинальная статья от автора реакта, но в ангуляре принципы такие же)

    В нашем случае компоненты search и result - глупые компоненты, которые только и делают, что возвращают строку ввода (search) и отображают данные (result). Так же у нас имеется умный компонент searchResults, который знает как отреагировать на данные из search и правильно отобразить result.

    Search и Result ничего не должны знать об HttpService. Он в них не инжектится.

    SearchComponent:

    import { Component, EventEmitter, Output } from '@angular/core';
    
    @Component({
        selector: 'search',
        templateUrl: './result.component.html',
        styleUrls: ['./result.component.scss']
    })
    export class SearchComponent {
    
        public query: string;
    
        @Output() onQuery: EventEmitter<string> = new EventEmitter();
    
        constructor() {}
    
        public handlerEnterSearch() {
            this.onQuery.emit(this.query)
        }
    }


    search.html:

    <div class="input-group input-group-lg p-5">
        <input
            [(ngModel)]="query"
            type="text"
            class="form-control"
            placeholder="Что ищем?"
            (keyup.enter)="handlerEnterSearch()"
        >
        <div class="input-group-append">
            <button class="btn btn-primary" type="button" (click)="handlerEnterSearch()">Найти фильм</button>
        </div>
    </div>


    result.component.ts

    import { Component, OnInit, Input } from '@angular/core';
    import { HttpService } from '../http.service'
    
    @Component({
      selector: 'result',
      templateUrl: './result.component.html',
      styleUrls: ['./result.component.scss']
    })
    export class ResultComponent implements OnInit {
    
      // Вот эти items выводятся в html результата
      @Input()
      items: any[];
    
      constructor(){}
    }


    search-result.html:

    <search (onQuery)="doSearch($event)">
    <result [items]="result">


    search-result.component.ts:

    import { Component, OnInit } from '@angular/core';
    import { HttpService } from '../http.service'
    
    @Component({
        selector: 'search-result',
        templateUrl: './search-result.component.html',
        styleUrls: ['./search-result.component.scss']
    })
    export class SearchResultComponent implements OnInit {
    
        items:any[];
    
        constructor(private httpService: HttpService){
    
        }
    
        // Вот это неудачная часть. Её можно сделать веселее, но для этого необходимо понимать как устроен RxJS.
        // Я не знаю как это объяснить без написания отдельной статьи.
        // На первое время такой подход сойдёт.
        doSearch(query: string) {
            this.httpService.getFilms(query).subscribe((items) => {
              this.items = items;
            })
        }
    }


    Использование сервисов для передачи данных между компонентами в ангуляре - это самые распространённые грабли во фреймворке. Причём эти грабли настолько хитрые, что большинство программистов даже не понимает что ходит по ним. Самый верный способ не наступать на грабли - это забыть навсегда про private и public переменные в сервисах (другими словами сервис не должен иметь состояние). Без этого можно жить и причём легко и спокойно если начать использовать NxRx для хранения состояния системы.
    Ответ написан
    2 комментария
  • Как в RxJS сделать переодичный вызов в n времени, только после завершения текущей итерации?

    search
    @search
    мама говорит что я особенный
    Как-то так:

    this.httpClient.request(...).pipe(
      repeatWhen(complete => complete.pipe(delay(20000))
    ).subscribe(result => console.log(result))
    Ответ написан
    Комментировать
  • Как передать контекст в импортированную фукцию?

    search
    @search
    мама говорит что я особенный
    Стрелочная функция получает контекст той области где она была объявлена, а не вызвана.

    Вот что вам нужно: https://developer.mozilla.org/en-US/docs/Web/JavaS...

    Контекст передаётся первым аргументом в .call:

    function1 () {
       function2.call(this);
    }
    Ответ написан
    4 комментария
  • Как лучше проверить правильность маршрута react-routerv4?

    search
    @search
    мама говорит что я особенный
    Вот статья как раз об этом https://tylermcginnis.com/react-router-protected-r...

    Делаете компонент PrivateRoute (в вашем случае его можно назвать по-другому, например PrivatePageRoute) и в нём проверяете, можно или нельзя. И если нельзя, то показываете сообщение об ошибке или выводите <Redirect to={...}> чтоб редиректнуть куда надо.
    Ответ написан
    Комментировать
  • Какой из вариантов более оптимизирован при деструктуризации?

    search
    @search
    мама говорит что я особенный
    Это влияет на конечный размер бандла.

    Webpack делает tree shaking: подключает только то что было импортировано. В первом случае будет подключена только одна иконка. Во втором все, даже если вы пользуетесь только одной. Поэтому первый вариант всегда предпочтительнее.
    Ответ написан
    1 комментарий
  • Как делают такое меню?

    search
    @search
    мама говорит что я особенный
    В CSS есть такая штука - media queries (https://developer.mozilla.org/ru/docs/Web/CSS/Medi...

    Это про адаптивный дизайн.

    В идеале, вашему приложению должно быть плевать на каком типе устройства оно отображается (комп, планшет, смартфон, часы и т.п.). Единственное что его должно интересовать - это как адаптировать дизайн под текущий размер экрана. Вот для этого и нужны медиазапросы. В вашем примере CSS код будет выглядеть как-то так:

    /* прячем тег с классом .b  при ширине экрана меньше чем 479px */
    @media (max-width: 479px) {
      .b {
        display: none;
      }
    }
    
    /* прячем тег с классом .a  при ширине экрана больше чем 480px */
    @media (min-width: 480px) {
      .a {
        display: none;
      }
    }


    В общем приближении, почти все мобилы имеют разрешение < 480px в ширину.

    Такие дела.

    Вот тут подробнее https://habr.com/en/sandbox/89063/
    Ответ написан
    1 комментарий
  • Как используя redux saga сохранять данные редьюсера в localstorage?

    search
    @search
    мама говорит что я особенный
    То что вас интересует, в народе называется rehydration и saga не совсем об этом. Будет как гвоздь, микроскопом забитый. Вот подходящая библиотека https://github.com/rt2zz/redux-persist

    Или вот этот комментарий от одного из авторов редакса о том как достичь желаемого без библиотеки https://stackoverflow.com/a/35675304/379949
    Ответ написан
    Комментировать
  • Property 'title' does not exist on type, Argument of type?

    search
    @search
    мама говорит что я особенный
    Потому что this.request(id) возвращает или faceProductList[][] или faceProductList[].

    А array.filter(({title}) => title.includes(valueSearch)) однозначно обрабатывает данные как faceProductList[] и не учитывает faceProductList[][].

    Можно сделать

    public async handler(id: string, valueSearch: string) { 
            await this.request(id)
              .then((array: faceProductList[]) => { 
                ...

    для того чтоб ошибка ушла.

    Но проблема неоднозначности останется и однажды вылезет в виде бага.

    На вашем месте я бы сделал как-то так:

    public async request(id: string): Promise<faceProductList[][]> {
      const res = await fetch(`${this.url}${id}`);
      const resArr: faceProductList[] | faceProductList[][]  = await res.json();
      if (resArr.length === 0) {
        return resArr;
      }
    
      if (Array.isArray(resArr[0])) {
        return resArr;
      }
    
      return [resArr];
    }


    не могу гарантировать что это заработает сразу, возможно прийдётся подпилить. Но направление мысли должно быть понятным.

    Плюс этого подхода - вы будете избавлены от проверки на "а что именно вернула request, faceProductList[] или faceProductList[][] ?" при каждом чихе.
    Ответ написан
    1 комментарий