Вопросы по тегу: rxjs

(27)

Использование массива из Observable Object с ngFor и Async Pipe Angular 2

Я пытаюсь понять, как использовать Observables в Angular 2. У меня есть эта служба:import {Injectable, EventEmitter, ViewChild} from '@angular/core'; import {Observable} from "rxjs/Observable"; import {Subject} from "rxjs/Subject"; import {BehaviorSubject} from "rxjs/Rx"; import {Availabilities} from './availabilities-interface' @Injectable() export class AppointmentChoiceStore { public _appointmentChoices: BehaviorSubject = new BehaviorSubject({"availabilities": [''], "length": 0}) constructor() {} getAppointments() { return this.asObservable(this._appointmentChoices) } asObservable(subject: Subject) { return new Observable(fn => subject.subscribe(fn)); } } Этот BehaviorSubject получает новые значения из другой службы:that._appointmentChoiceStore._appointmentChoices.next(parseObject) Я подписываюсь на него в виде наблюдаемого в компоненте, в котором я хочу его отобразить:import {Component, OnInit, AfterViewInit} from '@angular/core' import {AppointmentChoiceStore} from '../shared/appointment-choice-service' import {Observable} from 'rxjs/Observable' import {Subject} from 'rxjs/Subject' import {BehaviorSubject} from "rxjs/Rx"; import {Availabilities} from '../shared/availabilities-interface' declare const moment: any @Component({ selector: 'my-appointment-choice', template: require('./appointmentchoice-template.html'), styles: [require('./appointmentchoice-style.css')], pipes: [CustomPipe] }) export class AppointmentChoiceComponent implements OnInit, AfterViewInit { private _nextFourAppointments: Observable constructor(private _appointmentChoiceStore: AppointmentChoiceStore) { this._appointmentChoiceStore.getAppointments().subscribe(function(value) { this._nextFourAppointments = value }) } } И попытка отобразить в представлении так: {{appointment | date: 'EEE' | uppercase}} Однако доступность еще не является свойством наблюдаемого объекта, поэтому она выдает ошибку, хотя я определяю ее в интерфейсе доступности следующим образом:export interface Availabilities { "availabilities": string[], "length": number } Как я могу асинхронно отобразить массив из наблюдаемого объекта с помощью асинхронного канала и *ngFor? Я получаю сообщение об ошибке:browser_adapter.js:77 ORIGINAL EXCEPTION: TypeError: Cannot read property 'availabilties' of undefined
C

C. Kearns

6 лет назад

Ответов: 4

Как «ждать» двух наблюдаемых в RxJS

В моем приложении есть что-то вроде:this._personService.getName(id) .concat(this._documentService.getDocument()) .subscribe((response) => { console.log(response) this.showForm() }); //Output: // [getnameResult] // [getDocumentResult] // I want: // [getnameResult][getDocumentResult] Затем я получаю два отдельных результата: сначала _personService, а затем _documentService. Как я могу дождаться обоих результатов перед вызовом this.showForm() для завершения, а затем манипулировать результатами каждого из них.
g

gog

5 лет назад

Ответов: 8

TypeError: вы предоставили недопустимый объект, где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable

Я пытаюсь сопоставить из сервисного вызова, но получаю сообщение об ошибке. Посмотрел подписка не определена в angular 2? и там сказано, что для подписки нам нужно вернуться изнутри операторов. У меня также есть операторы возврата.Вот мой код:checkLogin(): Observable { вернуть этот сервис .получить данные() .карта( (ответ) => { это.данные = ответ; this.checkservice = истина; вернуть истину; }, (ошибка) => { // отладчик; this.router.navigate(["новая страница"]); console.log(ошибка); вернуть ложь; } ) .поймать((е) => { вернуть е; }); } Журнал ошибок: TypeError: Вы указали недопустимый объект там, где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable
A

Aakash Thakur

5 лет назад

Ответов: 21

Rxjs: Observable.combineLatest против Observable.forkJoin

Мне интересно, в чем разница между Observable.combineLatest и Observable.forkJoin?Насколько я понимаю, единственная разница в том, что forkJoin ожидает завершения Observables, а combineLatest возвращает последние значения.
T

Tuong Le

5 лет назад

Ответов: 3

Angular 4 Interceptor retry requests after token refresh

Hi I am trying to figure out how implement the new angular interceptors and handle 401 unauthorized errors by refreshing the token and retrying the request. This is the guide I have been following: https://ryanchenkie.com/angular-authentication-using-the-http-client-and-http-interceptors I am successfully caching the failed requests and can refresh the token but I cannot figure out how to resend the requests that previously failed. I also want to get this to work with the resolvers I am currently using. token.interceptor.ts return next.handle( request ).do(( event: HttpEvent ) => { if ( event instanceof HttpResponse ) { // do stuff with response if you want } }, ( err: any ) => { if ( err instanceof HttpErrorResponse ) { if ( err.status === 401 ) { console.log( err ); this.auth.collectFailedRequest( request ); this.auth.refreshToken().subscribe( resp => { if ( !resp ) { console.log( "Invalid" ); } else { this.auth.retryFailedRequests(); } } ); } } } ); authentication.service.ts cachedRequests: Array> = []; public collectFailedRequest ( request ): void { this.cachedRequests.push( request ); } public retryFailedRequests (): void { // retry the requests. this method can // be called after the token is refreshed this.cachedRequests.forEach( request => { request = request.clone( { setHeaders: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: `Bearer ${ this.getToken() }` } } ); //??What to do here } ); } The above retryFailedRequests() file is what I can't figure out. How do I resend the requests and make them available to the route through the resolver after retrying? This is all the relevant code if that helps: https://gist.github.com/joshharms/00d8159900897dc5bed45757e30405f9
K

Kovaci

5 лет назад

Ответов: 11

Преобразовать обещание в наблюдаемое

Я пытаюсь осмыслить наблюдаемые. Мне нравится, как наблюдаемые объекты решают проблемы разработки и читабельности. Как я читал, польза огромна.Наблюдаемые в HTTP и коллекциях кажутся простыми. Как я могу преобразовать что-то подобное в наблюдаемый образец.Это из моего служебного компонента для аутентификации. Я бы предпочел, чтобы это работало так же, как и другие HTTP-сервисы в Angular2 - с поддержкой обработчиков данных, ошибок и завершения.firebase.auth (). CreateUserWithEmailAndPassword (электронная почта, пароль) .then (функция (firebaseUser) { // делаем что-нибудь для обновления вашего UI-компонента // передаем объект пользователя в компонент пользовательского интерфейса }) .catch (функция (ошибка) { // Здесь обрабатываются ошибки. var errorCode = error.code; var errorMessage = error.message; // ... }); Любая помощь здесь будет очень признательна. Единственным альтернативным решением, которое у меня было, было создание EventEmitters. Но я думаю, что это ужасный способ делать что-то в разделе услуг
K

Krishnan Sriram

5 лет назад

Ответов: 9

Каков правильный способ поделиться результатом сетевого вызова Angular Http в RxJs 5?

Используя Http, мы вызываем метод, который выполняет сетевой вызов и возвращает наблюдаемый http:getCustomer () { вернуть this.http.get ('/ someUrl'). map (res => res.json ()); } Если мы возьмем эту наблюдаемую и добавим к ней несколько подписчиков:пусть сеть $ = getCustomer (); let subscriber1 = network $ .subscribe (...); пусть подписчик1 = сеть $ .subscribe (...); let subscriber2 = network $ .subscribe (...); пусть подписчик2 = сеть $ .subscribe (...); Что мы хотим сделать, так это убедиться, что это не вызовет множественных сетевых запросов.Это может показаться необычным сценарием, но на самом деле он довольно распространен: например, если вызывающий абонент подписывается на наблюдаемый объект для отображения сообщения об ошибке и передает его в шаблон с помощью асинхронного канала, у нас уже есть два подписчика.Как правильно это сделать в RxJs 5?А именно вроде нормально работает:getCustomer () { вернуть this.http.get ('/ someUrl'). map (res => res.json ()). share (); } Но разве это идиоматический способ сделать это в RxJs 5, или мы должны сделать что-то другое?Примечание: согласно Angular 5 new HttpClient, часть .map (res => res.json ()) во всех примерах теперь бесполезна, так как JSON результат теперь предполагается по умолчанию.
A

Angular University

6 лет назад

Ответов: 21

Observable.of is not a function

I am having issue with importing Observable.of function in my project. My Intellij sees everything. In my code I have:import {Observable} from 'rxjs/Observable'; and in my code I use it like that:return Observable.of(res); Any ideas?
u

uksz

6 лет назад

Ответов: 18

Наблюдаемый, наконец, при подписке

Согласно этот artcle, onComplete и onError функции subscribe являются взаимоисключающими.Означает либо onError, либо onComplete события будут запускаться в моей подписке. У меня есть логический блок, который должен выполняться независимо от того, получаю ли я сообщение об ошибке или успешно завершаю поток информации.Я искал что-то вроде , наконец, в python, но все, что я нашел, это наконец, который необходимо прикрепить к наблюдаемое я создаю.Но я хочу использовать эту логику только при подписке и после завершения потока, успешно или с ошибкой.Есть идеи?
A

Amir Tugi

5 лет назад

Ответов: 3

Свойство catch не существует для типа Observable<any>

На странице документации Angular 2 для использования службы Http есть пример.getHeroes (): Observable { return this.http.get(this.url) .map(this.extractData) .catch(this.handleError); } Я клонировал проект angular2-webpack-starter и сам добавил указанный выше код.Я импортировал Observable, используя import {Observable} from 'rxjs/Observable'; Я предполагаю, что свойства Observable также импортированы (.map работает). Посмотрел журнал изменений для rxjs.beta-6, и ничего не упоминается о catch.
B

BrianRT

6 лет назад

Ответов: 3

Как я могу закрыть раскрывающийся список при щелчке снаружи?

Я хотел бы закрыть раскрывающееся меню входа в систему, когда пользователь щелкнет в любом месте за пределами этого раскрывающегося списка, и я хотел бы сделать это с помощью Angular2 и "подхода" Angular2 ...Я реализовал решение, но я действительно не уверен в нем. Я думаю, что должен быть самый простой способ добиться того же результата, так что если у вас есть идеи ... давайте обсудим :)!Вот моя реализация:Выпадающий компонент:Это компонент для моего раскрывающегося списка: Каждый раз, когда этот компонент становится видимым (например, когда пользователь нажимает кнопку, чтобы отобразить его), он подписывается на «глобальную» тему rxjs userMenu, хранящуюся в SubjectsService. И каждый раз при скрытии отписывается на эту тему. Каждый щелчок в любом месте внутри шаблона этого компонента запускает метод onClick (), который просто останавливает всплытие событий наверх (и компонент приложения) Вот кодexport class UserMenuComponent { _isVisible: boolean = false; _subscriptions: Subscription = null; constructor(public subjects: SubjectsService) { } onClick(event) { event.stopPropagation(); } set isVisible(v) { if( v ){ setTimeout( () => { this._subscriptions = this.subjects.userMenu.subscribe((e) => { this.isVisible = false; }) }, 0); } else { this._subscriptions.unsubscribe(); } this._isVisible = v; } get isVisible() { return this._isVisible; } } Компонент приложения:С другой стороны, есть компонент приложения (который является родителем раскрывающегося компонента): Этот компонент перехватывает каждое событие щелчка и генерирует один и тот же предмет rxjs (userMenu) Вот код:export class AppComponent { constructor( public subjects: SubjectsService) { document.addEventListener('click', () => this.onClick()); } onClick( ) { this.subjects.userMenu.next({}); } } Что меня беспокоит: Мне не очень нравится идея иметь глобальный субъект, который действует как связующее звено между этими компонентами. The setTimeout: Это необходимо, потому что вот что произойдет в противном случае, если пользователь нажмет кнопку, которая показывает раскрывающийся список: Пользователь нажимает кнопку (которая не является частью раскрывающегося списка), чтобы отобразить раскрывающийся список. Отображается раскрывающийся список и сразу подписывается на тему userMenu. Пузырь события клика поднимается до компонента приложения и перехватывается Компонент приложения генерирует событие в userMenu subject Компонент раскрывающегося списка перехватывает это действие в userMenu и скрывает раскрывающийся список. В конце раскрывающийся список никогда не отображается. Этот установленный тайм-аут задерживает подписку до конца текущей очереди кода JavaScript, что решает проблему, но, на мой взгляд, очень элегантно.Если вы знаете более чистые, лучшие, умные, быстрые или сильные решения, дайте мне знать :)!
C

Clement

6 лет назад

Ответов: 24

Для чего нужен pipe в RxJS?

Я думаю, что у меня есть базовая концепция, но есть некоторые неясностиВ общем, вот как я использую Observable:observable.subscribe (x => { }) Если я хочу отфильтровать данные, я могу использовать это:import { first, last, map, reduce, find, skipWhile } from 'rxjs/operators'; observable.pipe( map(x => {return x}), first() ).subscribe(x => { }) Я тоже могу это сделать:import 'rxjs / add / operator / map'; import 'rxjs / add / operator / first'; observable.map (x => {return x}). first (). subscribe (x => { }) Итак, мои вопросы: В чем разница? Если нет разницы, почему существует функция pipe? Почему этим функциям нужен другой импорт?
e

enno.void

4 года назад

Ответов: 5

оператор 'of' vs 'from'

Единственное различие между Observable.of и Observable.from форматом аргументов? Как Function.prototype.call и Function.prototype.apply?Observable.of(1,2,3).subscribe(() => {}) Observable.from([1,2,3]).subscribe(() => {})
x

xiaoke

5 лет назад

Ответов: 8

Angular 2 beta.17: свойство 'map' не существует для типа 'Observable<Response>'

Я только что обновился с Angular 2 beta16 до beta17, что, в свою очередь, требует rxjs 5.0.0-beta.6. (Список изменений здесь: https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta17-2016-04-28) В бета-версии 16 все работало хорошо в отношении функциональности Observable / map. Следующие ошибки возникли после обновления и возникают при попытке перенастройки машинописного текста: Свойство 'map' не существует для типа 'Observable' (везде, где я использовал карту с наблюдаемым) c: /path/node_modules/rxjs/add/operator/map.d.ts (2,16): ошибка TS2435: внешние модули не могут быть вложены в другие модули или пространства имен. c: /path/node_modules/rxjs/add/operator/map.d.ts (2,16): ошибка TS2436: объявление внешнего модуля не может указывать относительное имя модуля. Я видел этот вопрос / ответ, но это не решает проблему: Наблюдаемые ошибки с Angular2 beta.12 и RxJs 5 beta.3Мой appBoot.ts выглядит так (я уже ссылаюсь на rxjs / map): /// импортировать {bootstrap} из "angular2 / platform / browser"; импортировать {ROUTER_PROVIDERS} из 'angular2 / router'; импортировать {HTTP_PROVIDERS} из angular2 / http; [вещи] import 'rxjs / add / operator / map'; import 'rxjs / add / operator / toPromise'; импортировать {enableProdMode} из angular2 / core; импортировать {Заголовок} из 'angular2 / platform / browser'; // enableProdMode (); бутстрап (AppDesktopComponent, [ ROUTER_PROVIDERS, HTTP_PROVIDERS, Заголовок ]); Кто-нибудь знает, что происходит?
b

brando

6 лет назад

Ответов: 16

Подписка устарела: используйте наблюдателя вместо обратного вызова ошибки

Когда я запускаю линтер, он говорит:subscribe is deprecated: Use an observer instead of an error callback Код (из приложения angular 7 с angular-cli): this.userService.updateUser (данные) .pipe ( нажмите (() => {бла бла бла}) ).подписываться( this.handleUpdateResponse.bind (это), this.handleError.bind (это) ); Не знаю, что и как использовать ...Спасибо!
i

ismaestro

3 года назад

Ответов: 7

взять (1) против первого ()

Я нашел несколько реализаций AuthGuard, которые используют take (1). В своем проекте я использовал first ().Работают ли оба одинаково?import 'rxjs/add/operator/map'; import 'rxjs/add/operator/first'; import { Observable } from 'rxjs/Observable'; import { Injectable } from '@angular/core'; import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { AngularFire } from 'angularfire2'; @Injectable() export class AuthGuard implements CanActivate { constructor(private angularFire: AngularFire, private router: Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { return this.angularFire.auth.map( (auth) => { if (auth) { this.router.navigate(['/dashboard']); return false; } else { return true; } } ).first(); // Just change this to .take(1) } }
C

Calvin Ferrando

5 лет назад

Ответов: 6

node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected error after installation of Angular 6

I got an error of node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected. after the installation of Angular 6. Check the error:ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected. node_modules/rxjs/internal/types.d.ts(81,74): error TS1005: ';' expected. node_modules/rxjs/internal/types.d.ts(81,77): error TS1109: Expression expected.
S

SSP

3 года назад

Ответов: 17

Angular2 http.get() ,map(), subscribe() and observable pattern - basic understanding

Now, I have an initial page where I have three links. Once you click on the last 'friends' link, appropriate friends Component gets initiated. In there, I want to fetch/get list of my friends strored into friends.json file. Till now everything works fine. But I'm still a newbie for angular2's HTTP service using RxJs's observables, map, subscribe concept. I've tried to understand it and read few articles but until I get into practical work, I'm not gonna understand those concepts properly.Here I have already made plnkr which is working except HTTP related work.Plnkrmyfriends.ts import {Component,View,CORE_DIRECTIVES} from 'angular2/core'; import {Http, Response,HTTP_PROVIDERS} from 'angular2/http'; import 'rxjs/Rx'; @Component({ template: ` My Friends {{frnd.name}} is {{frnd.age}} years old. `, directive:[CORE_DIRECTIVES] }) export class FriendsList{ result:Array; constructor(http: Http) { console.log("Friends are being called"); // below code is new for me. So please show me correct way how to do it and please explain about .map and .subscribe functions and observable pattern. this.result = http.get('friends.json') .map(response => response.json()) .subscribe(result => this.result =result.json()); //Note : I want to fetch data into result object and display it through ngFor. } } Please guide and explain properly. I know it will be so beneficial to lots of new developers.
n

nyks

6 лет назад

Ответов: 3

Angular - "has no exported member 'Observable'"

Typescript code:import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { of } from 'rxjs/observable/of'; import { Hero } from './hero'; import { HEROES } from './mock-heroes'; @Injectable({ providedIn: 'root' }) export class HeroService { constructor() { } getHeroes(): Observable { return of(HEROES); } } error info: error TS2307: Cannot find module 'rxjs-compat/Observable'. node_modules/rxjs/observable/of.d.ts(1,15): error TS2307: Cannot find module 'rxjs-compat/observable/of'. src/app/hero.service.ts(2,10): error TS2305: Module '"F:/angular-tour-of-heroes/node_modules/rxjs/Observable"' has no exported member 'Observable'. src/app/hero.service.ts(15,12): error TS2304: Cannot find name 'of'. package.json file with Angular version:
T

Thomas Lee

4 года назад

Ответов: 15

Тема vs BehaviorSubject vs ReplaySubject в Angular

Я долго пытался понять эти 3: Тема BehaviorSubject Тема повтора Я хотел бы их использовать и знать, когда и почему, каковы преимущества их использования, и хотя я читал документацию, смотрел учебные пособия и искал в Google, я не смог понять этого.Так в чем их цель? Было бы очень полезно использовать реальный случай, который не требует даже кодирования.Я бы предпочел чистое объяснение, а не просто «a + b => c, на который вы подписаны ....»Спасибо
u

user6015054

5 лет назад

Ответов: 7

Что такое функция pipe () в Angular

Конвейеры - это фильтры для преобразования данных (форматов) в шаблоне.Я наткнулся на функцию pipe (), как показано ниже. Что именно означает эта функция pipe () в данном случае?return this.http.get(url) .pipe( tap(_ => this.log(`fetched hero id=${id}`)), catchError(this.handleError(`getHero id=${id}`)) );
D

Dinesh Sharma

4 года назад

Ответов: 5

Вернуть пустой наблюдаемый

Функция more () должна возвращать Observable из запроса на получениеэкспорт класса Collection { public more = (): Observable => { if (this.hasMore ()) { вернуть this.fetch (); } еще { // возвращаем пустой наблюдаемый } }; private fetch = (): Observable => { вернуть this.http.get ("some-url"). map ((res) => { вернуть res.json (); }); }; } В этом случае я могу выполнить запрос, только если hasMore () истинно, иначе я получаю сообщение об ошибке subscribe () function подписка не определена, как мне вернуть пустой Observable?this.collection.more (). Subscribe ( (res) => { console.log (res); }, (err) => { console.log (ошибка); } ); ОбновитьВ RXJS 6импорт {EMPTY} из 'rxjs' return EMPTY;
M

Murhaf Sousli

5 лет назад

Ответов: 11

Как создать Observable из статических данных, подобных http в Angular?

У меня есть служба, в которой есть этот метод:export class TestModelService { public testModel: TestModel; constructor( @Inject(Http) public http: Http) { } public fetchModel(uuid: string = undefined): Observable { if(!uuid) { //return Observable of JSON.stringify(new TestModel()); } else { return this.http.get("http://localhost:8080/myapp/api/model/" + uuid) .map(res => res.text()); } } } в конструкторе компонента подписываюсь так:export class MyComponent { testModel: TestModel; testModelService: TestModelService; constructor(@Inject(TestModelService) testModelService) { this.testModelService = testModelService; testService.fetchModel("29f4fddc-155a-4f26-9db6-5a431ecd5d44").subscribe( data => { this.testModel = FactModel.fromJson(JSON.parse(data)); }, err => console.log(err) ); } } Это работает, если объект поступает с сервера, но я пытаюсь создать наблюдаемый объект, который будет работать с заданным вызовом subscribe () для статической строки (это происходит, когда testModelService.fetchModel () не получает uuid), поэтому в обоих случаях обработка выполняется без проблем.
M

Michail Michailidis

6 лет назад

Ответов: 6

В чем разница между Subject и BehaviorSubject?

Я не понимаю разницы между Subject и BehaviorSubject. Просто в BehaviorSubject есть функция getValue ()?
M

Mike Jerred

5 лет назад

Ответов: 7

Angular / RxJS Когда мне следует отказаться от подписки на `Subscription`

Когда мне следует сохранять экземпляры Subscription и вызывать unsubscribe () в течение жизненного цикла ngOnDestroy, а когда я могу просто игнорировать их?Сохранение всех подписок вносит большой беспорядок в код компонента.Руководство по HTTP-клиенту игнорировать такие подписки:getHeroes () { this.heroService.getHeroes () .подписываться( heroes => this.heroes = герои, error => this.errorMessage = ошибка); } В то же время Руководство по маршруту и ​​навигации говорит, что: В конце концов, мы переместимся в другое место. Маршрутизатор удалит этот компонент из DOM и уничтожит его. Нам нужно убрать за собой, прежде чем это произойдет. В частности, мы должны отказаться от подписки до того, как Angular уничтожит компонент. В противном случае может возникнуть утечка памяти. Отписываемся от нашего Observable методом ngOnDestroy. приватная подписка: любая; ngOnInit () { this.sub = this.route.params.subscribe (params => { пусть id = + params ['id']; // (+) преобразует строку id в число this.service.getHero (id) .then (герой => this.hero = герой); }); } ngOnDestroy () { this.sub.unsubscribe (); }
S

Sergey Tihon

6 лет назад

Ответов: 26

В чем разница между обещаниями и наблюдаемыми?

В чем разница между Promise и Observable в Angular?Примеры каждого из них помогут понять оба случая. В каком сценарии мы можем использовать каждый случай?
R

Rohit

6 лет назад

Ответов: 31

BehaviorSubject vs Observable?

Я изучаю шаблоны Angular RxJs и не понимаю разницы между BehaviorSubject и Observable.Насколько я понимаю, BehaviorSubject - это значение, которое может меняться со временем (на него можно подписаться, и подписчики могут получать обновленные результаты). Похоже, это та же цель, что и Observable.Когда бы вы использовали Observable по сравнению с BehaviorSubject? Есть ли преимущества использования BehaviorSubject по сравнению с Observable или наоборот?
K

Kevin Mark

5 лет назад

Ответов: 11

2022 WebDevInsider