Как получить параметры запроса из 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...
  }
}

Вы используете роутеры? Откуда берется 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');
  }
}

Это полезно, спасибо. Начиная с версии 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 за указание на это.


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;
  }

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 - это имя, используемое в вашем компоненте маршрутизации приложений :)


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.


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;
  }
}

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


-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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.