Hi I'm new to ionic and I'm trying to use nav push to send my username to the next page.
Here are my codes on my first .js page, note that Index is the name of my 2nd page which has been imported.
this.nav.push(Index, { paramUser: 'asd' });
now on my second page.
import {Component} from "#angular/core";
import {NavController, NavParams} from "ionic-angular";
#Component({
templateUrl: 'build/pages/index/index.html'
})
export class Index {
static get parameters() {
return [[NavController]];
}
constructor(nav, navParams) {
this.nav = nav;
this.navParams = navParams;
this.navParams.get('paramUser');
}
}
however i kept am receiving 'undefined' when I moved on to my second page, may I know what's the issue here?
Brother you may missing second element in array which returns from static get parameters function see below how it is.
static get parameters() {
return [[NavController], [NavParams]];
}
Other than this everything looks ok in your code sample.
Please let me know if solve otherwise will research more.
webonerd
Related
I am a beginner in Angular and I was making a simple app wherein there is a employee list. I have currently hardcoded the details of imaginary employees. I have used set and get methods to filter the employee array when someone searches(wants to filter).
The problem I am having with the logic I used is that when nothing is entered in the filter box(when the page reloads or when user backspaces what was written) I want to show the complete user list but that is not happening when the page reloads . If a user enters something and then clears the search box then the full list is shown but not when page is reloaded.
Here is the ts file for that component:
private _eidfilter:string='';
get eidfilter():string {
return this._eidfilter
}
set eidfilter(value : string){
this._eidfilter=value
this.filteredemp=this.performfilter(value.toString());
}
filteredemp:Emp[]=[];
performfilter(filterBy:string): Emp[] {
if(filterBy.trim.length==0){
return this.employees;
}
else{
return this.employees.filter((employee:Emp)=>employee.eid.toString()==filterBy)
}
}
employees:Emp[]=[
{eid:1,name:"Vikram",age:29,department:"WebDev",skills:5},
{eid:2,name:"Vetaal",age:30,department:"ML",skills:3.5},]
Import ChangeDetectorRef
import { ChangeDetectorRef } from '#angular/core';
Inject it into Constructor
constructor(private chRef: ChangeDetectorRef) { }
Use it into Your ngOninit() method after filling employees array.
NOTE : use this Change Detection Technique after you get data into the Array You're using.
ngOnInit(): void {
this.yourMethodToFillEmployeeDetails();
this.chRef.detectChanges();
}
For now filteredemp is initially empty, and receives values only on eidfilter change.
You can fix this by setting default value for filteredemp, or by filling filteredemp on load.
What I want to do is shuffle or riffle a number and then stock it in an array, to later use it in the view, but I only want this when I reload the page. The problem is that every time I go to the component it generate a new number. This number I am using to shuffle the order of my products in the view, order:
{{number}}.
IN THE COMPONENT:
public accesoriosJson:any
private current_value:any
constructor(private accesoriosService: AccesoriosService){
this.accesoriosService.getAccesorios().subscribe(respuesta =>{
this.accesoriosJson = respuesta;
this.accesoriosJson.map(currentValue =>{
this.current_value = currentValue;
this.current_value.random = Math.ceil(Math.random()*10);
})
})
}
IN THE VIEW:
<div class="div" *ngFor='let accesorios of accesoriosJson' style="order:{{accesorios.random}};" routerLink="{{accesorios.name}}">
<div class="lupa"><i class="fas fa-search"></i></div>
<img src="{{accesorios.logo}}">
</div>
</section>
I tried to do something with window.onload, but clearly I do not know how to use angular, and also I do not have so much experience with typescript, if somebody could help me I would really appreciate it! Thank you!
It's a new number, because each time the page is revisited, the component is re-created (a new instance of the component is created).
What you need is a singleton service. Singleton services are the ones that only have a single instance across the application.
So you can:
Create the service
Move your code to the service
Inject the service into your component.
That way, your number will instantiate only once, when the application loads, and each time you revisit the page, you will see the same number.
Documentation on singleton services.
Documentation on how to inject a service.
This is a very broad description, but as you can see from the information in the links provided, the full answer won't fit here.
A simple way is to subscribe to the router events and that will get you the page refreshed or not. NavigationStart is used to tell if the page loaded the first time.
import { Component, OnDestroy } from '#angular/core';
import { NavigationStart, Router } from '#angular/router';
import { Subscription } from 'rxjs';
export let browserRefresh = false;
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnDestroy {
name = 'Angular 6';
subscription: Subscription;
constructor(private router: Router) {
this.subscription = router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
browserRefresh = !router.navigated;
}
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Working Example:
https://stackblitz.com/edit/angular-r6-detect-browser-refresh
A solution can be to generate your random number into the root component (propably app-component if you didn't changed it) in the ngOnInit() function. Please avoid put code in constructor() function.
After your number as been generated, you can pass it to all the components you want : by using #Input/#Output if you have a parent/child hierarchy, or by using a service if you want to share it to every component wherever you want
I'm very new to the world of Angular (loving it so far).
We have an Angular 1 (JS) app that we plan to convert to the latest Angular 2 (8.3.9) version.
One thing that was done in the old app, was make use of the $scope object, and then set the CSS stylesheet link in the root index.html dynamically based on a query parameter in the requesting URL.
Using ngStyle or ngClass to update indiviudal elements in a document it cool, but,
How do we handle changing the entire style sheets on loading the app in Angular 2?
Everything is encapsulated inside the component, and styles specified in the angular.json file are built into the "deployable.js" file. Is it possible to change it at runtime?
This link appears to be the closest example:
Generate dynamic css based on variables angular
, but still doesn't quite solve the problem at the root index.html file.
The Current OLD Version
Url Arrives:
http://someserver:port/app?css=http://linktoCSs/cssFile.css
css query param is pulled into a global variable and stored on scope called css_url,
In index.html (starting page)
<link rel="stylesheet" ng-href="{{css_url}}">
and the app starts using whatever style sheet this link provides.
The NEW Angular 2 (version 8.3.9)
We want to mimic the above behavior that we were able to achieve in the JS version. Pull a URL from a QueryParam pointing to some CSS file, and that CSS URL can be injected into the main index.html to change the entire apps styles in one go, or dynamically access the style-sheet in code to update everything in one go.
In short, we want 1 app that can be styled by a CSS file, based off a queryparam.
All thoughts and comments will be greatly appreciated.
After a lot of digging around, finally found the solution I was looking for.
And it was so straight forward, hope this helps others that might be needing to do the same thing..
Get the css path from query params and then Inject the Document into a TS file...
append the link to the head of the document.
I did this in a Router Guard using canActivate.
I got the query param from the routerstatesnpshot like so:
Inject the DOCUMENT( don't forget the import) in the constructor
http://server.com/xxx&broker=1&client=2&css=http://cssServer.com/my_dynamic_stylesheet.css
import { DOCUMENT } from '#angular/common';
#Inject(DOCUMENT) private document: Document
this.setDynamicStyle(state.root.queryParamMap.get('css'));
setDynamicStyle(cssURL: string) {
const head = this.document.getElementsByTagName('head')[0];
const style = this.document.createElement('link');
style.id = 'css-styling';
style.rel = 'stylesheet';
style.href = `${cssURL}`;
head.appendChild(style);
}
Thanks to:
https://juristr.com/blog/2019/08/dynamically-load-css-angular-cli/
This appears to be a fairly common issue, updating styling dynamically, and I can't find anything where people have attempted to override the entire CSS file/s for an Anuglar 2 app, post compilation.
What I ended up doing (for now)...
On GitHub link: https://github.com/angular/angular/issues/9343
Thanks to: peteboere
Created a directive like
import {Directive, ElementRef, Input} from '#angular/core';
#Directive({
selector: '[cssProps]',
})
export class CSSPropsDirective {
#Input() cssProps: any;
constructor(private element: ElementRef) {}
ngOnChanges({cssProps})
{
if (cssProps && cssProps.currentValue)
{
const {style} = this.element.nativeElement;
for (const [k, v] of Object.entries(cssProps.currentValue))
{
style.setProperty(k, v);
}
}
}
}
Which unfortunately means placing the cssProps on EACH and EVERY element in my documents that needs styling... like:
<div class="panel-heading" [cssProps]="cssStyling">
Then I created a simple Service to fetch styling in a JSON format like,
{--backgroundColor: "black"}
in the css file per component I used custom css properties, to handle these.
background: var(--backgroundColor)
--backgroundColor: #008000;
NOTE TO SELF, doing this at app-root level, might mean not having to apply styles per component css file..., but we will still need to apply the directive to each element we want to style dynamically. ViewEncapsulation will need to be NONE across lower components.
Then, on an httpClient call every 10 seconds (for now) like:
import { HttpClient } from '#angular/common/http';
import { Subject, Subscription } from 'rxjs';
import { Injectable } from '#angular/core';
#Injectable({providedIn: 'root'})
export class StyleSerivce {
styleChanged = new Subject<any>();
interval = new Subscription();
styles:any;
constructor(private httpClient: HttpClient) { }
retrieveStyleFrom() {
setInterval(() => {
this.httpClient.get('https://serverName/stylesss.json')
.subscribe(data => {
console.log(data);
this.styles = data;
this.styleChanged.next(this.styles);
})
}, 10000);
}
}
I subscribed to the styleChange in the respective components like:
this.styleSub = this.styleService.styleChanged.subscribe((styleNow) => {
this.cssStyling = styleNow;
})
and with cssStyling bound to my directive, as I update the DB where the JSON is stored,
I can update the screen dynamically... (after the 10 second elapse)
This works, but the pain of setting this on each tag to make it dynamically updatable from DB/JSON updates is hectic.
I would not call this a solution to the initial problem, but a painful workaround.
My app displays a profile name that can be edited. When i edit it it changes, great. When i navigate and come back, the data reset's.
I've tried holding the data (profile name) as a String variable, I've tried holding the data as a list and displaying the name with String[0] to display the unshifted profile name.
First go
<h3>{{profileService.profileName}}'s Profile</h3>
this.profileService.changeName(this.pName);
changeName(data){
this.profileName = data;
}
Second go
<h3>{{profileService.profileNames[0]}}'s Profile</h3>
this.profileService.changeName(this.pName);
changeName(data){
this.profileNames.unshift(data);
}
So, again, this updates initially when I go from edit-page to home-page. When I go to another page and return, the updated profile name is MISSING. Thanks!
Have you made sure that:
The service is provided for both the home page and the edit page?
This can be done by:
in app.module.ts (I guess you want your changes to persist for the whole application)
#NgModule({
declarations:[
//your components here
],
imports:[
//your modules here
],
providers:[
ProfileService //and other services
]
})
or in profile.service.ts
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'// which means there will be a single instance of the service in the whole application
})
export class ProfileService {
}
The navigation between the home and edit page is using Angular Router: https://angular.io/guide/router
I have a component that's called in different areas of my site which has more components nested inside of it that I want to display depending on the route. I came up with this solution.
import { Component } from '#angular/core';
var routeLocation = window.location.pathname;
#Component({
selector: 'asset-packs',
template: `<h1>Asset Packs</h1>
<asset-expand *ngIf="routeLocation.indexOf('expand') > 0"></asset-expand>
<asset-newbus *ngIf="routeLocation.indexOf('rebrand') > 0"></asset-newbus>
`
})
export class PointAssetsComponent {
}
my intention was to use
var routeLocation = window.location.pathname;
to pull the url from the browser and save it into a variable which I could then call in the *ngIf statement as
*ngIf="routeLocation.indexOf('expand') > 0"
As you can see from the quoted out variables I've tried a few different ways of accessing the URL as well as swapping the exact text I want to look for for a variable with the text stored in it. Either which way I'm getting the undefined error.
So far I haven't been able to find any examples of
.indexOf()
specifically being used in ngular 2, but from what I've seen about it I'm using the right syntax with it. I was originally trying to use
.contains()
and got the same error. When I delete the ngIf statements both components show up without a problem. It's just when I add them in that this problem starts occurring.
I've come across a few other articles on this issue where they said it was a bug caused by AngularFire and FireBird modules in Node. I checked and neither of those are in my app.
The only thing I figure is it has to be something with the syntax or I'm not importing something that makes the
window.location.etc
parts work. Does anybody know what's causing this and how to fix it?
You could do this in your ts file:
import { Router } from '#angular/router';
export class PointAssetsComponent {
public navExpand:boolean = false;
public navRebrand:boolean = false;
constructor(private router: Router) {
}
if (this.router.url.substring(0,7) === '/expand'){
this.navExpand = true;
} else if (this.router.url.substring(0,8) === '/rebrand'){
this.navRebrand = true;
}
HTML
#Component({
selector: 'asset-packs',
template: `<h1>Asset Packs</h1>
<asset-expand *ngIf="navExpand"></asset-expand>
<asset-newbus *ngIf="navRebrand"></asset-newbus>
`
})