Reputation: 5055
This is stackblitz demo (not exact but somewhat idea of what problem I am trying to tell)
I have defined a const
in src/app/constants/app.ts
export const DEFAULT_FILTERS = {
"page":1,
"perPage":10,
"sortOrder": "asc",
"tag":"all",
"sortBy":"firstname"
}
I have done this to remove clutter from different interconnected components where I need to define filters as a variable and then using it.
listing.component.ts
import { DEFAULT_FILTERS} from '@app/constants/app';
export class listingComponent implements OnInit, OnDestroy {
private for = someOtherconstant; // some other const used here.
private params = {
"filters": DEFAULT_FILTERS,
"for": this.for
}
getNewRecords(pageNum) {
console.log('default filters', DEFAULT_FILTERS)
this.currentPageNum = pageNum;
this.params['filters']['page'] = this.currentPageNum;
this._service.triggerCallForUsersObservable(this.careGroupParams)
}
}
The console.log
inside getNewRecords
prints DEFAULT_FILTERS
which I have changed no where still the page index inside DEFAULT_FILTERS
because I am changing this.params['filters']['page'] = this.currentPageNum
. Why?
I need a global const
which I want to keep const
for diff components so that I can reset the filters value whenever required.
EDIT:
If I use object.freeze
then I am not able to change the property this.params
like:
this.params['filters']['name'] = 'xyz'
So what could be the other way to keep DEFAULT_FILTER
as global variable/const
and then I can access it or change it and change the new variable which is accessing it but not the global val?
Upvotes: 2
Views: 6985
Reputation: 11
You can use deep copy, as it allocates separate memory location for the new object, so changing "this.params" values in your case will not change the value of page index inside "DEFAULT_FILTERS".
Ex. var employee = { eid: "E102", ename: "Jack", eaddress: "New York", salary: 50000 } var newEmployee = JSON.parse(JSON.stringify(employee)); // DEEP COPY
Now if we make any change in "newEmployee" it will not make any change in "employee" as we are doing deep copy.
But if we simply do,
var newEmployee = employee; // SHALLOW COPY
and now we make any change in "newEmployee" it will reflect in "employee" as well, as we are doing shallow copy.
Upvotes: 0
Reputation: 39432
Here's what you can do to fix this. Create a class
for Constants instead of a const
. Declare a static
getter variable inside it. static
so that you don't have to create an instance of this class to use the constant. And then use it in your Component class. Something along the lines of this:
Constants Class
export class Constants {
static get DEFAULT_FILTERS() {
"page": 1,
"perPage": 10,
"sortOrder": "asc",
"tag": "all",
"sortBy": "firstname"
}
}
Component Class
import {
Component,
Input
} from '@angular/core';
import {
Constants
} from '../app/constants/app'
@Component({
selector: 'hello',
template: `<h1> {{name}}!</h1>
<button (click)='getUsers()'>click me to see change in default filters const</button>`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
@Input() name: string;
params = {
"filters": Constants.DEFAULT_FILTERS
}
getUsers() {
console.log('default filters', Constants.DEFAULT_FILTERS)
this.params['filters']['page'] = 2;
}
}
Upvotes: 1
Reputation: 9800
You can copy the const
value instead of referencing it. However, as soon as you copy, it loses the connection with the original value; nonetheless, as it is a const
value, it is not supposed to be changed, so it wouldn't be a problem.
You can copy the object by using the ...
(spread) operator like the code bellow:
private params = {
"filters": { ...DEFAULT_FILTERS },
"for": this.for
}
Alternatively, you can create a class with a static property getter that always return a fresh object so there is no risk of losing the original value.
class Constants {
static get DEFAULT_FILTERS() {
return {
"page": 1,
"perPage": 10,
"sortOrder": "asc",
"tag": "all",
"sortBy": "firstname"
}
}
}
let myDefaultFilter = Constants.DEFAULT_FILTERS;
myDefaultFilter.page = 2;
Constants.DEFAULT_FILTERS.page = 3; // forcing changes
console.log(myDefaultFilter.page) // changes
console.log(Constants.DEFAULT_FILTERS.page) // stays the same
Upvotes: 3