ui-router: Converting URL parameters

Is there a way to seamlessly transform URL parameters? Let me illustrate with a scenario. Our URL structure is like this:

/shopping/nuts/:productId
/shopping/berries/:productId
/shopping/juice/:productId

The products in our app, fetched from an API, may look like this:

{ type: 'berry', price: 123, text: 'lorem ipsum', id: '12345' }

There's a discrepancy between the plural and singular forms: The URL uses the plural form (e.g. 'berries'), while the API delivers the singular form ('berry').

A portion of our state definition appears as follows:

.state('shop.product', {
  url: '/shopping/:type/:productId',
  templateUrl: 'type.html',
  controller: 'TypeController'
})

Issue: I have to call a function in every controller to transform the $state parameter into singular form (toSingular($stateParams.type)). And when creating links, I need to do the reverse transformation. This process is tedious and error-prone.

Therefore, my ideal solution would be:

For URL /shopping/berries/12345, $stateParams.type === 'berry'. When generating the URL using

ui-sref="shop.product({type: 'berry', id: '12345'})"
, it should return /shopping/berries/12345.

I've been struggling to find a suitable integration point for this logic. Any feedback is highly appreciated!

Answer №1

Incorporating a Unique Parameter Type

Explore this resource for more information on creating custom parameter types.

When registering a custom parameter type, remember that it must both encode and decode the value within the URL effectively.

For encoding, convert the internal representation (such as 'nut' or 'berry') into a string format suitable for display in the URL.

On the other hand, decoding involves taking the string from the URL and transforming it back into the original internal value.

 var productTypes = {
    berry: ['berries', 'berry'],
    nut: ['nuts', 'nut'],
    juice: ['juice'],
  }

  $urlMatcherFactoryProvider.type('productType', {
    encode: val => 
      productTypes[val][0],
    decode: string =>
      Object.keys(productTypes).find(key => productTypes[key].indexOf(string) !== -1),
  });

To see this concept in action, check out this interactive example on Plunker: Interactive Example Link

Answer №2

Suggested resolution:

In the case where your URL appears as /store/fruits/56789, it indicates that you have not included stateParams.type. When type is properly included, the URL should read as store/fruit/56789. For instance, constructing a URL like

store.product({type: 'a', id: '34'})
will result in a URL format of store/a/34. This pertains to the usage of stateParams within the URL structure. It seems likely that incorrect URLs are being generated for non-state pages, hence causing navigation issues. To address this, consider utilizing $urlRouterProvider.otherwise() for better clarity.

$stateProvider.state('store', {
  url: '/store'
})
.state('store.product', {
  url: '/:type/:id'
});
$urlRouterProvider.otherwise('/');

If an erroneous URL is provided, the redirection will default to '/'

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

Using jest in typescript to simulate HttpRequest body and InvocationContext in @azure/functions

I have the following function and I am trying to write a test for it, but I'm having trouble figuring out how to mock HttpRequest import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions"; export async function ...

Display current weather conditions with the Open Weather API (featuring weather icons)

Hello everyone, I need some help from the community. I am currently working on a weather app using the openweather API. However, I'm facing an issue with displaying the weather conditions icon for each city. I have stored every icon id in a new array ...

The Vue.js reactivity system does not detect changes when a property is updated within a WebRTC callback

Is Vue.js component creation becoming a challenge for you? Imagine creating a small component that requires permissions for the camera and microphone from the user, displaying that stream on a canvas. Sounds simple, right? However, let's face reality ...

What is the best way to retrieve the results of an indexedDb request beyond the limitations of its callback function?

I am working on a form that has an input box which I want to auto-complete with values from an IndexedDb objectStore. Currently, it is functioning with two overlapping input boxes, using a simple array. However, I am looking to make it work with the values ...

Utilize jQuery post to send a request to a particular function located at a given URL

Is there a way to accomplish the following: $.post( "functions.php", { name: "John", time: "2pm" }) .done(function( data ) { alert( "Data Loaded: " + data ); }); Instead, is it possible to direct your data to a particular function in "functions.p ...

Exploring the relationship between AngularJS and HTTP headers

I am trying to send a custom HTTP header to the REST service with every request I make. My setup involves using Apache HTTP Web Server, and below is the code snippet I have created: app.config(['$httpProvider', function($httpProvider){ if(!$ ...

I possess an array containing objects of different lengths depending on the chosen city. How can I pinpoint the element that contains an object with a specific property?

My dilemma arises from the fact that the length of an array depends on the selected city, making it impossible to select elements using an index. In this scenario, I need to devise a method to choose elements based on the value of one of their properties. ...

What is the best way to showcase response information on the website interface?

Recently, I have been utilizing GET requests to the github API: axios.get('https://api.github.com/users/roadtocode822') .then(function (response) { console.log(response.data); }) Successfully retrieving the response data. This particula ...

Running jQuery scripts through PHP

$("#bt-potrdi").click( function(e) { e.stopPropagation(); $("#belina").css({"z-index":200}); $("body").addClass("ext"); $("#vpisok_frame").css({"z-index":250}).fadeIn(200); }); Upon clicking the button, the ...

Handle empty response from endpoint response

I'm facing an issue with a method that subscribes to an endpoint for a response. In some cases, the endpoint returns null and I need to handle this scenario. public list: Array<any>; this.GetList(this.getListRequest) .subscribe( (resp) =& ...

Clicking on the delete option will remove the corresponding row of Firebase data

I am encountering an issue that appears to be easy but causing trouble. My goal is to delete a specific row in an HTML table containing data from Firebase. I have managed to delete the entire parent node of users in Firebase when clicking on "Delete" withi ...

Rails Navigation Issue: JQuery Confirmation Not Functioning Properly

Having a Rails app, I wanted to replicate the onunload effect to prompt before leaving changes. During my search, I came across Are You Sure?. After implementing it on a form, I noticed that it only works on page refreshes and not on links that take you a ...

Angular routes cause a glitch in the Bootstrap navbar, causing it to shift to the left on certain active

Apologies for the simple question, I am new to web design and couldn't find a solution even after extensive googling and searching. The issue I am facing is that when clicking on "EX5" or "EX6" in my navbar, it shifts to the left side of the screen i ...

Learn how to integrate Bootstrap with Vue.js TreeView in this tutorial

If you're looking to create a treeview using Vue.js, the code structure would resemble something like this: HTML: <!-- item template --> <script type="text/x-template" id="item-template"> <li> <div ...

Preventing Users from Selecting Past Dates in Material-UI datetime-local TextField

I am striving to prevent selection of past dates but have not been successful so far. Below is the code snippet: <TextField variant="outlined" id="datetime-local" label="Select Date and Time" placeholder="Sele ...

The complexity surrounding various versions of jQuery, the .noConflict method, and the jQuery migrate feature

I was tasked with making a large-scale website responsive, and decided to utilize Bootstrap as the framework. However, I encountered issues due to the jQuery version (v1.8.2) being used. In my development environment, I resolved this by including the follo ...

Retrieving checkbox list values using jQuery

I am working with a div that contains some checkboxes. I want to write code so that when a button is clicked, it will retrieve the names of all the checked checkboxes. Can you provide guidance on how to achieve this? <div id="MyDiv"> .... <td> ...

Unlocking the Secrets of Laravel Blade Integration in a Script File

I am attempting to create a customized store locator application using the guidance provided in this useful tutorial on Google Maps and Laravel 5. While going through various queries related to integrating Google Maps with Laravel, I came across these info ...

There was an issue encountered when attempting to access the stackoverflow api

I am currently attempting to retrieve all questions tagged with ipv4 from stackoverflow using the stackoverflow API. However, I encountered the following error message: No 'Access-Control-Allow-Origin' header is present on the requested resource. ...

Navigating properties and linking information in React

I'm currently tackling a project that requires me to pass data to two distinct functional components. While my axios call to the API appears to be functioning properly, along with setting the state using hooks, I am continuously encountering two pers ...