Angular 8 routerLinks create decoded href with # to %23 - html

I have one problem with generating routerLinks in my application.
I retrieve the menu structure from API. Fetch it when app initializes, store it in the Observable and then simply show it.
The part of the structure im showing is pretty straightforward.
<ng-container *ngFor="let item of menuItems">
<h5 class="dekstop-submenu-heading">{{ item.name }}</h5>
<ul class="desktop-submenu-list" [ngClass]="{'desktop-submenu-list-wrap': item.subItems.length > 5}">
<li *ngFor="let subItem of item.subItems" class="desktop-submenu-item">
<a [attr.aria-label]="subItem.name" [routerLink]="subItem.url">{{ subItem.name }}</a>
</li>
</ul>
</ng-container>
The problem comes when there is an url with an anchor to specific page part, i.e. /some-component/description#specific.
Angular routerLink is generated properly but the href isn't, it is decoded to /some-component/description%23specific.
I can't get rid of this behaviour, I've tried decoding it with decodeURIComponent but with no effects..
Do you have any idea what causes such behaviour? Such a simply thing makes a lot of troubles..

You just need to send the urlĀ and the element id in a separate directive.
If you have control over the subItem.url then just rename it to /description and subItem.fragment to specific and then change the template like this:
[routerLink]="subItem.url" [fragment]="subItem.fragment"
If you don't have control over subItem.url, then just perform a split on %23:
const [url, ...fragment] = subItem.url.split('%23');
[routerLink]="url" [fragment]="fragent.join('%23')"

You can handle query params in routerLink directive
I think this will help you
<a [attr.aria-label]="subItem.name" [routerLink]="subItem.url"
queryParamsHandling="preserve">{{ subItem.name }}</a>

Related

Is it possible to use a dynamic value in asp-route-{value}?

I have Razor Page with the following piece of code to create a link that adds a dynamic value to the route when clicked. This works perfectly.
<a class="page-link" asp-route-systemRightsPage="#(i.Index)">#i.Index</a>
Now, I have different values for the route, in this case I'm using systemRightsPage, but I also have 3 more types that I can navigate to (personsPage, personRightsPage, errorsPage), and so on.
Is it possible to use somehow a dynamic value on the asp-route-{value} part?
I tried using this:
<a class="page-link" asp-route-#(RouteValue)="#(i.Index)">#i.Index</a>
This code renders correctly in HTML to:
<a class="page-link" asp-route-personpage="2">2</a>
But the link doesn't work anymore, as nothing happens if I click it.
Has anyone done anything similar?
You can use the all-route-data attribute to pass arbitrary parameter names and their values:
#{var values = new Dictionary<string,string>{{"personpage", "2"}};}
<a asp-page="/whatever" asp-all-route-data="values">Click</a>
https://www.learnrazorpages.com/razor-pages/tag-helpers/anchor-tag-helper

appending rows to an existing data list in angular

I'm displaying data from a back-end system. The data comes from a table that is for a window of time receiving new rows. I have a mechanism to fetch those rows within an angular timer. My question, given the template below, how can i add those new rows to my list as shown below without redrawing the entire list.
template: `
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
<p>Heroes:</p>
<ul>
<li *ngFor="let hero of heroes">
{{ hero }}
</li>
</ul>
`
Since you are using angular 2+ version, you need not worry about the redrawing list part as it will handle it automatically using shadow DOM.
have you looked the obserbvables from rxjs?
http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html
they can provide a variable that automaticaly updates with the new value provided

Tooltip not working inside a tag with ngFor attribute

Could someone explain to me why the tooltip in this piece of code using Angular 4 templates doesn't work?
<template ngFor let-channel [ngForOf]="channels">
<td>
<em *ngFor="let color of findBallsColor()" class="fa fa-circle {{ color }}" [tooltip]="id"></em>
</td>
</template>
<ng-template #id>
test
</ng-template>
If I remove the *ngFor inside the <em> tag it works fine (showing just one element obviously). I'm quite new to Angular so probably I'm missing some understanding of how it really works here.
EDIT
I found out the problem comes from the type returned from the Typescript function. In the code above, the list returned by findBallsColor() is actually an object that contains 4 fields. When I change it to just return a string it works. So the code looks similar to this:
HTML:
<template ngFor let-channel [ngForOf]="channels">
<td>
<em *ngFor="let color of findBallsColor()" class="fa fa-circle {{ status.color }}" [tooltip]="id"></em>
</td>
</template>
<ng-template #id>
test
</ng-template>
TS:
findBallsColor():any[] {
return [{"statut":"ERROR","name":"name","otherField":"value","anotherField":"value"}];
}
Does anyone know the why of this behaviour?
I had a similar problem, here's an excerpt from this Github issue, that details what is wrong with the way you get your data for your *ngFor.
Calling a function from the template is not a good practice and this is an example of why this recommendation exists.
When the tooltip is fired in the first case, it starts an angular detection cycle, which in turn calls items() again and it tries to show the tooltip again and it starts another angular detection cycle and it goes on and on and on repeatedly.
At first, the recommendation exists to avoid performance issues, but it has other consequences like in your case.
If you put a console.log in items(), you'll see it keeps being called again and again...
If calling a function is mandatory, use a pipe instead.
So, in your code, if you used a pipe or an observable or array of some sort, then your tooltip would work, but currently it just keeps calling the function.
This worked for me - add data-toggle="tooltip" to the html tag - aka the tooltip.
Then target the tooltip via the body $('body').tooltip({selector: '[data-toggle="tooltip"]'});

Django Aggregation in View

I would like to show the result of the query from the database on my html view.
When I run my raw sql aggregate query in the Django shell, I get the result I'm looking for. But when I pass the data into my html from the view, it does not show any data.
My views.py and I also have the model imported
def officehome(request):
"""Renders the office home page."""
assert isinstance(request, HttpRequest)
ordersrecieved = FbsOrderT.objects.count()
return render(
request,
'app/officehome.html',
{"ordersrecieved": ordersrecieved}
)
this is in the html view
<ul class="list-group">
<li class="list-group-item">
<h5 class="list-group-item-heading">Orders Received <span {ordersrecieved}></span></h5>
</li>
Would angular routing be a problem and not knowing when to execute the query.
This is wrong:
<h5 class="list-group-item-heading">Orders Received <span {ordersrecieved}></span></h5>
what you want is:
<h5 class="list-group-item-heading">Orders Received <span> {{ ordersrecieved }}</span></h5>
The way templating works is it converts {things which are in here to the python variable context} so if it is in the text of the html it will work if its an attribute of the span (as in <span {gergerg}>) then that might render but as nothing visible to the user. Also use {{ }} rather than { unless you specified a custom templating parser.

display binary image from db to angular partial view

I was trying to display image which is coming within the json object returning from an web api request. I'm able to display string, number and date/time in my angular partial but couldn't get the image displaying.
here is my json object which contains each field of my topic (model) class
<Topic>
<Body>dsadfsaadsfds</Body>
<Created>2014-06-15T00:00:00</Created>
<Flagged>false</Flagged>
<Id>1022</Id>
<PhotoFile>
iVBORw0KGgoAAAANSUhEUgAAB2wAAAOiCAIAAAAzNbBAAAABiWlDQ1BJQ0MgUHJvZmlsZQAAKBWtkT1LA0EQht+L0SgJGCRoCpEFRSzu5IxFTLTJB5iIRYgKane5nImQj+NyIfoD7Gy0EG0U9S+INhaWYqGFIAjB3yAEAi..........
(I want to post screen shot but i can't due to lack of reputations.....)
</PhotoFile>
<Replies i:nil="true"/>
<Title>csdaadsf</Title>
and here is my angular html partial:
<a data-ng-href="#/message/{{ i.id }}">{{ i.title }}</a>
</div>
<div class="date span2">
{{ i.created | date:"medium" }}
</div>
<div class="contents span12">
{{ i.body }}
</div>
<img ng-alt="" src="{{'data:image'+i.photofile}}" /> </div>
`
Since i can get other attributes working, my angular factory and controller should be working. Are there anything wrong with my syntax in angular partial view for displaying images? Thanks
You shouldn't be using the src attribute when using Angular expression as the value. Use ng-src instead, it will ensure the image don't show up before Angular has a chance to replace the expression.
If the sample payload you've shown is complete, the way you are forming the data URI is incomplete. Depending on the format of the image, the header should look like
data:image/png;base64,[things in the JSON]
You can read more about the format here