Angular2: Grabbing the hash fragment from a URL

Is there a way to retrieve the hash fragment using Angular2 from a URL structure that I don't have control over?

http://your-redirect-uri#access_token=ACCESS-TOKEN

After setting up my router configuration, it seems like everything after oauth is being ignored and I can't access the hash fragment in request.params or location.path. Any solutions?

Router config:

@RouteConfig([
{path: '/welcome', name: 'Welcome', component: WelcomeComponent, useAsDefault: true},
{path: '/landing/oauth', name: 'Landing', component: LandingComponent}  // this one

])

Answer №1

If you're in search of a solution:

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

export class MyComponent {

  constructor(
    private route: ActivatedRoute,
  ) { }

  retrieveHash(){
    this.route.fragment.subscribe((fragment: string) => {
        console.log("The hash fragment is visible => ", fragment)
    })
  }
}

Answer №2

Expanding further on the current responses, I want to discuss a simple method for parsing query parameters in the hash (particularly for a federated response) when the ActivatedRoute does not handle it directly.

this.route.fragment.subscribe(fragment => {
  const response = _.fromPairs(Array.from(new URLSearchParams(fragment)));
  response.access_token;
  response.id_token;
  response.expires_in;
  response.token_type;
});

Start by creating a new URLSearchParams object with the fragment to retrieve its values:

new URLSearchParams(fragment).get('access_token');

In most cases, this should be sufficient. However, if you wish to convert this into an object, you can use Array.from to convert URLSearchParams into an array of arrays in the format: [['key', 'value'], ...]. Then, lodash's _.fromPairs can transform this into an object.

Answer №3

Another option is to utilize ActivatedRouteSnapshot without the necessity of subscribing to all changes.

@Component({templateUrl:'./my-component.html'})
class MyComponent {
  constructor(route: ActivatedRoute) {
    const fragment: string = route.snapshot.fragment;
  }
}

Answer №4

After receiving feedback from nwayve, I have successfully incorporated their comment into my code using the power of RxJS pipes. Here is how it looks now:

this.route.fragment
  .pipe(
    map(fragment => new URLSearchParams(fragment)),
    map(params => ({
      access_token: params.get('access_token'),
      id_token: params.get('id_token'),
      error: params.get('error'),
    }))
  )
  .subscribe(res => console.log('', res));

Answer №5

If you are utilizing the ActivatedRoute class within your constructor, consider implementing this solution:

let parameters = this.route.snapshot.fragment;

const jsonData = JSON.parse(
    '{"' +
        decodeURI(parameters)
            .replace(/"/g, '\\"')
            .replace(/&/g, '","')
            .replace(/=/g, '":"') +
        '"}'
);

console.log(jsonData); // { json: "with your properties"}

Answer №6

Encountering a similar issue when making a request to the OAuth server using response_type=token, which redirects to

%REDIRECT_URI%#access_token=:access_token&token_type=:token_type&expires_in=:expires_in
.

The issue stems from the default routing configuration where direct access to sub-URLs is not handled properly. For example, %BASE_URL%/landing/oauth may not redirect to the expected LandingComponent.

To resolve this, I implemented the following configuration:

import { bootstrap } from '@angular/platform-browser-dynamic';
import { provide } from '@angular/core';
import { APP_BASE_HREF } from '@angular/common';
import { ROUTER_PROVIDERS } from '@angular/router';

import { AppComponent } from './components/app/app.component';

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    provide(APP_BASE_HREF, { useValue: '/' }) // this line
]);

Answer №7

One way to extract fragment data using vanilla JavaScript is by following this approach:

this.activatedRoute.fragment.subscribe(value => {
  let fragments = value.split('&')
  let fragmentData = {}
  fragments.forEach(item => {
    let pair = item.split('=')
    fragmentData[pair[0]] = pair[1]
  })
})

The extracted information will be stored in an object format for easy retrieval.

Answer №8

After attempting the method mentioned in a reference link, I encountered an unexpected result where the snapshot turned out to be an empty string. The solution that proved successful for me can be found at

The approach that worked in my case is illustrated below:

  ngOnInit(): void {
    this.route.fragment.subscribe({ 
        next: value => {
        if (value === null) {
          throw new Error('not implemented');
        }
        const access_token = new URLSearchParams(value).get('access_token')
        console.log({access_token})
      }
    });
  }

Answer №9

To obtain the URL fragment anytime, simply utilize this code snippet that leverages the Router service:

const urlTree = this.router.parseUrl(this.router.url);
console.log(urlTree.fragment); //access_token=ACCESS-TOKEN

Answer №10

This particular approach using Angular exclusively proved to be the most effective for addressing my issue.

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

constructor(
    private router: Router,) {}
...

ngOnInit() { 
    this.router.events.subscribe((event) => {
      if(event instanceof NavigationEnd) {
        console.log("route change url", event.url)
      }
    });
}

When navigating from a URL like http://localhost:8100/#/activity, it correctly logs /activity

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting issues with TypeScript D3 v4 module import functionality

As I embark on the journey of creating a miniature JS library using D3 to visualize line charts, I find myself navigating unfamiliar waters. However, I believe that deep diving into this project is the most effective way for me to learn. Below is the cont ...

The Angular Material Autocomplete component fails to show items upon upgrading the angular/material package to the newest version

Issue with Angular Material Autocomplete component not displaying items after updating angular/material package to the latest version. The autocomplete was functioning correctly with "@angular/material": "^2.0.0-beta.10" but encountered issues when update ...

What is the best way to obtain the dimensions of an image in Angular 2 (or newer) before uploading it to the server, and can this be accomplished without utilizing jQuery?

After searching through multiple resources, I realized that most of the solutions are written in jQuery. However, I am specifically looking for a solution in Typescript. The HTML code snippet is as follows: <input #coverFilesInput class="file-input" t ...

Angular 2: The linting error shows up as "Anticipated operands need to be of the same type or any"

So, I have this shared service file where a variable is defined like so: export class SharedService { activeModal: String; } Then, in my component file, I import the service and define it as follows: constructor(public sharedService: SharedService) ...

MobX React not causing re-render when props change

Just diving into MobX and encountering some roadblocks while trying to call async actions. In my store, there's an async function responsible for updating an observable array: export class AccountStore implements IAccountStore { @observable accounts ...

How to Redirect between Controllers in Nest.Js

I'm currently working with a module that looks like this: @Module({ imports: [], controllers: [AppController, AnotherController], providers: [], }) Within the AppController, I am attempting to implement res.redirect('/books') which r ...

Accessing Nested Arrays in Angular 8: Retrieving Data in HTML Template from Multiple Layers of Arrays

Hello there. I'm using an API that gives me the following data: (4) [{…}, {…}, {…}, {…}] 0: dueDate: "2018-03-26T00:00:00" priority: {priorityId: 1, priorityName: "Critical", priorityColor: "red"} statuses: Array(1) 0: ...

Typescript: Variable of unspecified type

Within my generator function called foo(), I am making a request to an external API using the fetch method. Once I receive the response data from the API, I then parse it as JSON. Encountering an issue, as Typescript is triggering an error message: An Obj ...

How can we use Javascript to determine if there are any duplicated IDs within an array containing multiple arrays?

Currently, I'm facing a challenge in identifying duplicated values within an array. Let's consider the scenario where we have an array of arrays: array = [ { id: 123, name: 'Emily', address: 'UK' }, { id: 123, name: ' ...

Modify typescript prior to typechecking

Consider the following TypeScript file: class A { private x? = 0; private y? = 0; f() { console.log(this.x, this.y); delete this.x; } } const a = new A(); a.f(); When building it in webpack using awesome-typescript-loader ...

What is the method for placing a title in the initial column with the help of v-simple-table from Vuetify.js?

I am interested in using the v-simple-table UI component from Vuetify.js to create a table similar to the one shown below. https://i.sstatic.net/QNdpJ.png After creating the code in codesandbox and previewing the output, I noticed that the title is not a ...

Angular Validators are behaving inconsistently, as they only work intermittently before stopping altogether once the application is

Why does my code sometimes behave differently after running for a while and then return to normal after restarting the Angular server without making any changes?The pop-up that says "please fill out this field" disappears when it shouldn't This is th ...

Showing the date object in a react component

As a new programmer, I decided to start with React hooks based on recommendations that it's easier to learn. However, I encountered an issue when trying to display the deliveryDate on the screen. React doesn't seem to accept objects as children, ...

Is it possible to incorporate JavaScript files into a TypeScript (ts, tsx) project that has already been built?

Recently, I was given a task to incorporate additional pages into the current project which has been developed using the following technologies: Laravel: 8.12 React: 17.0.2 NextJS: 10.0.9 Tailwind CSS: 2.0.4 React Query: 3.13.0 [ REST] TypeScript: 4.2.3 M ...

What are the methods used in TypeScript to implement features that are not available in JavaScript, despite TypeScript ultimately being compiled to JavaScript?

After transitioning from JavaScript to TypeScript, I discovered that TypeScript offers many features not found in JS, such as types. However, TypeScript is ultimately compiled down to JavaScript. How is it possible for a language like TypeScript to achie ...

Clear the input field once an item has been successfully added to the array

I'm working on a CRUD application using an array. Once I add an item to the array, the HTML input field doesn't clear or reset. I've searched online but couldn't find a reset method in Angular. How can I clear the input field after addi ...

Using Material UI with React and TypeScript

I need some assistance with organizing my menus correctly in React using TypeScript. Currently, they are displaying on top of each other instead of within their respective category menus. I have been struggling to find a solution and would appreciate any h ...

Utilizing Angular 14 to dynamically import modules during execution

I'm experimenting with dynamically importing modules in Angular 14 where the module paths are determined at runtime, but encountering the following error: Error: Cannot find module 'src/app/plugin1/plugin1.module' Github repro Manually spe ...

Encountering HttpErrorResponse when sending a Delete request in Angular

I need help troubleshooting an issue with sending a Delete request from my movie.component.ts file to delete a review. Unfortunately, I keep receiving the dreaded HttpErrorResponse error. Can anyone pinpoint where I may be making a mistake? Take a look at ...

Troubleshoot: TypeScript - Issue encountered while utilizing conditional types with enum in a generic function

I've run into a problem while working with a TypeScript function that uses conditional types based on an enum. The enum in question: export enum FactoryResult { INTERNAL_FORMALITY_CREATED_WITH_DOCS, INTERNAL_FORMALITY_INVALID_DOCS, INTERNAL_FOR ...