Как получить параметры запроса из URL в Angular 5?

181

Я использую Angular 5.0.3, я хотел бы запустить свое приложение с кучей параметров запроса, как /app?param1=hallo&param2=123. Каждый совет дан в Как получить параметры запроса из URL в Angular 2? не работает для меня.

Есть идеи, как заставить работать параметры запроса?

private getQueryParameter(key: string): string {
  const parameters = new URLSearchParams(window.location.search);
  return parameters.get(key);
}

Эта приватная функция помогает мне получить параметры, но я не думаю, что это правильный путь в новой среде Angular.

[обновление:] мое основное приложение выглядит

@Component({...})
export class AppComponent implements OnInit {

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}
Lars
источник
Вы используете роутеры? Откуда берется URL?
Винод
Да, есть ActivatedRoute. Я обновил свой вопрос, чтобы показать, как выглядит мой основной компонент.
Ларс
Вы также можете показать мне свою постоянную маршрута, где вы установили все маршруты?
Винод
const appRoutes: Routes = [{path: "one", компонент: PageOneComponent}, {path: "", redirectTo: "/ one", pathMatch: "full"}, {path: "**", redirectTo: "/ один"} ]; Мой маршрут постоянный. Я хотел бы получить все параметры в главном приложении, сохранить его в DTO, а затем перейти на другую страницу. Навигация по страницам работает, как и ожидалось, но параметры запроса я получаю в основном только с помощью моей функции 'getQueryParameter'. В вашем вопросе я понимаю, что существует нечто, о чем я забыл. Нужно ли где-нибудь отмечать имена моих параметров?
Ларс
Да, в ваших маршрутах вам также необходимо определить параметры. Если вы посмотрите документы маршрутизации на angular.io, вы увидите, как они определяют параметры для конкретного маршрута. Примерно так {path: 'abc /: param1', component: componentClassName}
Винод

Ответы:

239

В Angular 5 доступ к параметрам запроса осуществляется путем подписки на this.route.queryParams.

Пример: /app?param1=hallo&param2=123

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    console.log('Called Constructor');
    this.route.queryParams.subscribe(params => {
        this.param1 = params['param1'];
        this.param2 = params['param2'];
    });
}

в то время как переменные пути доступны this.route.snapshot.params

Пример: /param1/:param1/param2/:param2

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    this.param1 = this.route.snapshot.params.param1;
    this.param2 = this.route.snapshot.params.param2;
}
Виджаендра Мудигал
источник
15
Согласно документам Angular 6 , использование ActivatedRoute.queryParams и .params не рекомендуется и может быть признано устаревшим в будущих версиях; смотрите обновление здесь
grreeenn
1
@ShubhenduVaid объясните почему, они должны использовать ngOnInit вместо конструктора. Передовой практикой будет использование наблюдаемых RxJS, затем использование декларативного подхода при работе с наблюдаемыми, а затем использование асинхронной
передачи
118

Это самое чистое решение для меня

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

export class MyComponent {
  constructor(
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    const firstParam: string = this.route.snapshot.queryParamMap.get('firstParamKey');
    const secondParam: string = this.route.snapshot.queryParamMap.get('secondParamKey');
  }
}
dapperdan1985
источник
Это полезно, спасибо. Начиная с версии 6.0.8, я использую это, и оно работает для меня: this.route.snapshot.queryParams ["firstParamKey"]
Жидкий гид
2
Это работает для меня в Angular8. this.route.snapshot.queryParamMap работает. this.route.snapshot.paramMap не работает для меня.
Ромео Профийт
90

Я знаю, что OP попросил решение для Angular 5, но все же для всех, кто сталкивается с этим вопросом для более новых (6+) версий Angular. Ссылаясь на документы , касающиеся ActivatedRoute.queryParams (на которых основано большинство других ответов):

Два старых свойства все еще доступны. Они менее способны чем их замены, обескуражены и могут быть устаревшими в будущей версии Angular.

params - Observable, который содержит обязательные и дополнительные параметры, специфичные для маршрута. Вместо этого используйте paramMap.

queryParams - Observable, который содержит параметры запроса, доступные для всех маршрутов. Вместо этого используйте queryParamMap.

Согласно Документам , простой способ получить параметры запроса будет выглядеть следующим образом:

constructor(private route: ActivatedRoute) { }

ngOnInit() {
    this.param1 = this.route.snapshot.paramMap.get('param1');
    this.param2 = this.route.snapshot.paramMap.get('param2');
}

Для более продвинутых способов (например, расширенное повторное использование компонентов) см. Эту главу Документов.

РЕДАКТИРОВАТЬ:

Как правильно указано в комментариях ниже, этот ответ неверен - по крайней мере, для случая, указанного в OP.

OP запрашивает глобальные параметры запроса (/ app? Param1 = hallo & param2 = 123); в этом случае вы должны использовать queryParamMap (как в ответе @ dapperdan1985).

paramMap, с другой стороны, используется для параметров, специфичных для маршрута (например, / app /: param1 /: param2, в результате получается / app / hallo / 123).

Спасибо @JasonRoyle и @daka за указание на это.

grreeenn
источник
10
Разве это не должно использоваться, чтобы queryParamMapне paramMapполучить параметры строки запроса?
Джейсон Ройл
2
@JasonRoyle Кажется, ты прав, paramMapне работает.
Дака
1
Этот ответ нуждается в исправлении согласно комментариям выше.
Дака
@JasonRoyle, дака, ты прав, спасибо, что указал на это. Исправил ответ.
Grreeenn
Нашел идеальный рабочий код: jsonworld.com/blog/…
Сони Кумари
17

Вы также можете использовать HttpParams , например:

  getParamValueQueryString( paramName ) {
    const url = window.location.href;
    let paramValue;
    if (url.includes('?')) {
      const httpParams = new HttpParams({ fromString: url.split('?')[1] });
      paramValue = httpParams.get(paramName);
    }
    return paramValue;
  }
a5tr0
источник
1
Просто уточнить, у меня два домена указывают на разные языковые сайты. localhost / -> En, localhost /? lang = fr -> французский. И у меня есть маршрутизация path: '', redirectTo: '/list' . This.route.snapshot не работает для меня, потому что он redirectTo / list, который исключает 'lang' queryString. Но это решение работает для меня.
Райан Хуан,
Как @RyanHuang у меня такая же проблема. Но это решение сработало на моем первом испытании.
Gi1ber7
Найдите лучшее решение, чем указано выше: jsonworld.com/blog/…
Сони Кумари,
11
import { ParamMap, Router, ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

ngOnInit() {
    console.log(this.route.snapshot.queryParamMap);
}

ОБНОВИТЬ

import { Router, RouterStateSnapshot } from '@angular/router';

export class LoginComponent {
    constructor(private router: Router) {
        const snapshot: RouterStateSnapshot = router.routerState.snapshot;
        console.log(snapshot);  // <-- hope it helps
    }
}
Дмитрий Гринько
источник
6
этого кажется недостаточно, я получаю ActivatedRouteSnapshot, но queryParams - пустой объект, params также пуст и .queryParamMap.get ('name') возвращает ноль. Похоже, что ngOnInit () пока рано получать такие параметры запроса.
Ларс
на самом деле, если вы хотите получить эти параметры, вы должны изменить свой маршрут.
Дмитрий Гринько
У меня около 10 параметров в разном порядке. Поэтому я должен использовать именованные параметры запроса. И как мне установить мой основной AppComponent, чтобы понять, что есть 10 параметров. url / myprogram? a = 1 & b = 2 & c = 4 ... у меня проблемы? Нужно ли направлять каждый параметр в другой компонент? Надеюсь нет.
Ларс
Вы пробовали это? this.route.snapshot.queryParamMap
Дмитрий Гринько
1
@DmitryGrinko размещение идентификатора объекта в маршруте не является плохим паттерном, оно позволяет получить глубокую ссылку на подробный вид.
Карл
5

Параметры запроса и пути (угловой 8)

Для URL, например, https://myapp.com/user/666/read?age=23 используйте

import { combineLatest } from 'rxjs';
// ...

combineLatest( [this.route.paramMap, this.route.queryParamMap] )
  .subscribe( ([pathParams, queryParams]) => {
    let userId = pathParams.get('userId');    // =666
    let age    = queryParams.get('age');      // =23
    // ...
  })

ОБНОВИТЬ

В случае, если вы используете this.router.navigate([someUrl]);и параметры вашего запроса встроены в someUrlстроку, то angular кодирует URL, и вы получаете что-то вроде этого https://myapp.com/user/666/read%3Fage%323 - и выше решение даст неправильный результат ( queryParams будет пустым, и параметры пути могут быть приклеены к последнему параметру пути, если он находится в конце пути). В этом случае измените способ навигации на этот

this.router.navigateByUrl(someUrl);
Камил Келчевски
источник
1
Спасибо @Kamil Kiełczewski, вы спасли мой день
Тан Нгуен
4

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

Следующий код отлично подходит для моего использования и не требует дополнительных модулей или импорта.

  GetParam(name){
    const results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
    if(!results){
      return 0;
    }
    return results[1] || 0;
  }

  PrintParams() {
    console.log('param1 = ' + this.GetParam('param1'));
    console.log('param2 = ' + this.GetParam('param2'));
  }

http://localhost:4200/?param1=hello&param2=123 выходы:

param1 = hello
param2 = 123
камыш
источник
3

Angular Router предоставляет метод parseUrl (url: string), который анализирует url в UrlTree . Одним из свойств UrlTree являются queryParams. Таким образом, вы можете сделать что-то вроде:

this.router.parseUrl(this.router.url).queryParams[key] || '';
Адам Михалак
источник
Пожалуйста, не размещайте несколько одинаковых ответов на разные вопросы. Вот несколько полезных советов об этой практике здесь
Дэвид Бак
Используйте это, если вам не нужно иметь дело с изменениями URL, т.е. параметры уже доступны в текущем URL. Сделайте это видимым способом иначе.
Том
2

К сожалению, самое чистое решение - не самое расширяемое решение. В последних версиях Angular предлагается в других ответах, что вы можете легко получить параметры запроса, используя ActivatedRoute Injectible и, в частности, используя любое из свойств снимка:

this.route.snapshot.queryParamMap.get('param')

или свойство подписки (используется в случаях, когда строка запроса будет обновляться, например, при переходе по идентификаторам пользователя):

this.route.queryParamMap.subscribe(params => console.log(params));

Я здесь, чтобы сказать вам, что у этих решений есть существенный недостаток, который не был решен в течение некоторого времени: https://github.com/angular/angular/issues/12157

В общем, единственное пуленепробиваемое решение - использовать старый добрый ванильный javascript. В этом случае я создал сервис для манипулирования URL:

import { Injectable } from '@angular/core';
import { IUrl } from './iurl';

@Injectable()
export class UrlService {
    static parseQuery(url: string): IUrl {
        const query = url.slice(url.indexOf('?')+1).split('&').reduce( (acc,query) => {
            const parts = query.split('=');
            acc[parts[0]] = parts[1];
            return acc;
        }, {});

        return {
            a: query['a'],
            b: query['b'],
            c: query['c'],
            d: query['d'],
            e: query['e']
        }
    }
}
Донато
источник
1

Когда у вас есть пустой объект маршрута, это в основном связано с тем, что вы не используете router-outlet в вашем app.component.html.

Без этого вы не сможете получить значимый объект маршрута с непустыми субобъектами, особенно params & queryParams.

Попробуйте добавить <router-outlet><router-outlet>прямо перед вызовом <app-main-component></app-main-component>

Перед этим убедитесь, что у вас есть готовый параметр запроса в app-routing>, который экспортирует класс Route, используемый компонентом App:

param: '/param/:dynamicParam', path: MyMainComponent

Последнее, конечно, чтобы получить ваш параметр, я лично использую, this.route.snapshot.params.dynamicParamгде dynamicParam - это имя, используемое в вашем компоненте маршрутизации приложений :)

andrea06590
источник
1

Будьте осторожны с вашими маршрутами. «RedirectTo» удалит | удалит любой параметр запроса.

const appRoutes: Routes [
 {path: "one", component: PageOneComponent},
 {path: "two", component: PageTwoComponent},
 {path: "", redirectTo: "/one", pathMatch: full},
 {path: "**", redirectTo: "/two"}
]

Я вызвал мой основной компонент с параметрами запроса, такими как "/ main? Param1 = a & param2 = b, и предположил, что мои параметры запроса поступают в метод" ngOnInit () "в главном компоненте, прежде чем перенаправление перенаправления вступит в силу.

Но это неправильно. Перенаправление произойдет раньше, удалит параметры запроса и вызовет метод ngOnInit () в главном компоненте без параметров запроса.

Я изменил третью линию моих маршрутов на

{path: "", component: PageOneComponent},

и теперь мои параметры запроса доступны в основных компонентах ngOnInit, а также в PageOneComponent.

Lars
источник
1

Найдено в: Родительские компоненты получают пустые параметры из ActivatedRoute

Работал для меня:

import {Component, OnDestroy, OnInit} from '@angular/core';
import { Router, ActivatedRoute, Params, RoutesRecognized } from '@angular/router';

@Component({
  selector: 'app-navigation-bar',
  templateUrl: './navigation-bar.component.html',
  styleUrls: ['./navigation-bar.component.scss']
})
export class NavigationBarComponent implements OnInit, OnDestroy {
  private sub: any;
  constructor(private route: ActivatedRoute, private router: Router) {}

  ngOnInit() {
    this.sub = this.router.events.subscribe(val => {
      if (val instanceof RoutesRecognized) {
        console.log(val.state.root.firstChild.params);
      }
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

}
Йонатан Аялон
источник
0

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

Я предполагаю, что у меня есть вариант использования, аналогичный исходному вопросу Ларса.

Для меня вариант использования, например, отслеживание рефералов:

Angular работает mycoolpage.com, с хеш-маршрутизацией, поэтому mycoolpage.comперенаправляет на mycoolpage.com/#/. Однако для реферальной ссылки такая ссылка также mycoolpage.com?referrer=fooдолжна быть пригодной для использования. К сожалению, Angular немедленно удаляет параметры запроса, переходя непосредственно к mycoolpage.com/#/.

Любой трюк с использованием пустого компонента + AuthGuard и получением queryParamsилиqueryParamMap , к сожалению, не работает для меня. Они всегда были пустыми.

Мое хакерское решение в конечном итоге заключалось в том, чтобы обрабатывать это в небольшом скрипте, в index.htmlкотором можно получить полный URL с параметрами запроса. Затем я получаю значение параметра запроса с помощью строковых манипуляций и устанавливаю его в объекте окна. Затем отдельный сервис обрабатывает получение идентификатора из объекта окна.

скрипт index.html

const paramIndex = window.location.href.indexOf('referrer=');
if (!window.myRef && paramIndex > 0) {
  let param = window.location.href.substring(paramIndex);
  param = param.split('&')[0];
  param = param.substr(param.indexOf('=')+1);
  window.myRef = param;
}

обслуживание

declare var window: any;

@Injectable()
export class ReferrerService {

  getReferrerId() {
    if (window.myRef) {
      return window.myRef;
    }
    return null;
  }
}
seBaka28
источник
0

Простое решение

 // in routing file
       {
            path: 'checkout/:cartId/:addressId',
            loadChildren: () => import('./pages/checkout/checkout.module').then(m => m.CheckoutPageModule)
          },

    // in Component file

            import { Router, ActivatedRoute } from '@angular/router';

                 constructor(
                      private _Router: ActivatedRoute
                  ) { }

                  ngOnInit() {
                    this.cartId = this._Router.snapshot.params.cartId;
                    this.addressId = this._Router.snapshot.params.addressId;
                    console.log(this.addressId, "addressId")
                    console.log(this.cartId, "cartId")
                  }
Шашват Гупта
источник
0

HTTP: // локальный: 4200 / продукты заказ = популярный

Мы можем получить доступ к параметру запроса заказа следующим образом:

this.route.queryParams
      .filter(params => params.order)
      .subscribe(params => {
        console.log(params)// {order: "popular"}

        this.order = params.order;
        console.log(this.order); // popular
      });
  }

Также существует queryParamMap, который возвращает наблюдаемое с объектом paramMap.

Учитывая следующий URL-адрес маршрута:

HTTP: // локальный: 4200 / продукты заказ = популярный & фильтр = новый

this.route.queryParamMap.subscribe(params => {
  this.orderObj = {...params.keys, ...params};
});

Источник - https://alligator.io/angular/query-parameters/

Сан Джайси
источник
0

Я думаю, что Angular 8:

ActivatedRoute.paramsбыл заменен на ActivatedRoute.paramMap ActivatedRoute.queryParamsбыл заменен на ActivatedRoute.queryParamMap

Marvin
источник
-1
/*
Example below url with two param (type and name) 
URL : http://localhost:4200/updatePolicy?type=Medicare%20Insurance&name=FutrueInsurance
*/ 
  constructor(private route: ActivatedRoute) {
    //Read url query parameter `enter code here`
  this.route.queryParams.subscribe(params => {
    this.name= params['type'];
    this.type= params['name'];
    alert(this.type);
    alert(this.name);

 });

  }
Кадзи Ислам
источник
-9

Если вы не используете Angular router, попробуйте запросить строку . Установить его

npm install --save querystring

к вашему проекту. В вашем компоненте сделать что-то вроде этого

import * as qs from 'querystring';
...
ngOnInit() {
   const params = qs.parse(window.location.search.substring(1));
   ...
}

Это substring(1)необходимо, потому что если у вас есть что-то вроде этого, '/mypage?foo=bar'то имя ключа для будет?foo

Чук Ли
источник