How to get the next id from the array when paging?
I have a button that turns the pages. I need to remain in this component, change the ID in the address bar and thus I will change the information on the site. Data coming to me, look like this:
{
"users": [
{
"id": "3135",
"name": "Lulu"
},
{
"id": "8173",
"name": "Lala"
},
{
"id": "5783",
"name": "Lolo"
}
]
I am outputting detailed information about the user by getting an id. My navigation has looks like:
{ path: 'list', component: ListComponent },
{ path: '', redirectTo: '/list ', pathMatch: 'full' },
{ path: 'details/:id', component: DetailComponent }
I have a button, by pressing which the transition from '/details/Id' to 'details/nextId'. But this button does not work. This is a request for the next ID in the service. (I get the data from Database API)
private users: User = new Array<User>();
private locator = (u: User, id: number) => u.id === id;
getNextId(id: number): number {
let index = this.users.findIndex(u => this.locator(u, id));
if (index > -1) {
return this.users[this.users.length > index + 2
? index + 1 : 0].id;
} else {
return id || 0;
}}
HTML:
<button class="next-user" [routerLink]="['details', userService.getNextId(user.id)]" routerLinkActive="active">
Next User
</button>
DetailsListComponent:
private userService: UserService,
private activeRoute: ActivatedRoute,
private location: Location,
private router: Router) {
activeRoute.params.subscribe(params => {
this.detail = params['details'] === 'details';
let id = params['id'];
if (id !== null) {
Object.assign(this.user, userService.getNextId(id));
}
});
}
detail: boolean = true;
I searched the Internet and here the answer to this question, but found only suitable for php. Please, help me. What am I doing wrong? I just recently began to study angular 7 and do not always understand what to do.
I do not know how to explain it correctly, how to explain my problem. But I will try, I have a page that displays a list of my users. Clicking on the user opens a new page with more detailed information about it. In order not to go back to the page with a list of users and not to select the next user, a page with detailed information about the user assumes the presence of the Next button. When I click on this button, the array is iterated, it is determined by which ID the page is currently open and which ID is the next in this array, after which the page goes to the next ID. That is, the same page is opened, but the information on it is about another user who is following the list after the previous user.
But my button is currently not working and I do not understand why.
html angular typescript
add a comment |
I have a button that turns the pages. I need to remain in this component, change the ID in the address bar and thus I will change the information on the site. Data coming to me, look like this:
{
"users": [
{
"id": "3135",
"name": "Lulu"
},
{
"id": "8173",
"name": "Lala"
},
{
"id": "5783",
"name": "Lolo"
}
]
I am outputting detailed information about the user by getting an id. My navigation has looks like:
{ path: 'list', component: ListComponent },
{ path: '', redirectTo: '/list ', pathMatch: 'full' },
{ path: 'details/:id', component: DetailComponent }
I have a button, by pressing which the transition from '/details/Id' to 'details/nextId'. But this button does not work. This is a request for the next ID in the service. (I get the data from Database API)
private users: User = new Array<User>();
private locator = (u: User, id: number) => u.id === id;
getNextId(id: number): number {
let index = this.users.findIndex(u => this.locator(u, id));
if (index > -1) {
return this.users[this.users.length > index + 2
? index + 1 : 0].id;
} else {
return id || 0;
}}
HTML:
<button class="next-user" [routerLink]="['details', userService.getNextId(user.id)]" routerLinkActive="active">
Next User
</button>
DetailsListComponent:
private userService: UserService,
private activeRoute: ActivatedRoute,
private location: Location,
private router: Router) {
activeRoute.params.subscribe(params => {
this.detail = params['details'] === 'details';
let id = params['id'];
if (id !== null) {
Object.assign(this.user, userService.getNextId(id));
}
});
}
detail: boolean = true;
I searched the Internet and here the answer to this question, but found only suitable for php. Please, help me. What am I doing wrong? I just recently began to study angular 7 and do not always understand what to do.
I do not know how to explain it correctly, how to explain my problem. But I will try, I have a page that displays a list of my users. Clicking on the user opens a new page with more detailed information about it. In order not to go back to the page with a list of users and not to select the next user, a page with detailed information about the user assumes the presence of the Next button. When I click on this button, the array is iterated, it is determined by which ID the page is currently open and which ID is the next in this array, after which the page goes to the next ID. That is, the same page is opened, but the information on it is about another user who is following the list after the previous user.
But my button is currently not working and I do not understand why.
html angular typescript
1
Can you post your html
– programoholic
Nov 21 '18 at 12:59
Can you please specify what exactly you mean by doesn't work? Is there some error or wrong id, etc?
– Daniil Andreyevich Baunov
Nov 21 '18 at 13:00
There are no errors in the IDE terminal or the console. How many do not press the button, nothing changes.
– LillyZhuk
Nov 21 '18 at 13:22
Thanks for clarification. I updated the answer have a look.
– Daniil Andreyevich Baunov
Nov 21 '18 at 16:00
@LillyZhuk did you try ?
– programoholic
Nov 22 '18 at 8:47
add a comment |
I have a button that turns the pages. I need to remain in this component, change the ID in the address bar and thus I will change the information on the site. Data coming to me, look like this:
{
"users": [
{
"id": "3135",
"name": "Lulu"
},
{
"id": "8173",
"name": "Lala"
},
{
"id": "5783",
"name": "Lolo"
}
]
I am outputting detailed information about the user by getting an id. My navigation has looks like:
{ path: 'list', component: ListComponent },
{ path: '', redirectTo: '/list ', pathMatch: 'full' },
{ path: 'details/:id', component: DetailComponent }
I have a button, by pressing which the transition from '/details/Id' to 'details/nextId'. But this button does not work. This is a request for the next ID in the service. (I get the data from Database API)
private users: User = new Array<User>();
private locator = (u: User, id: number) => u.id === id;
getNextId(id: number): number {
let index = this.users.findIndex(u => this.locator(u, id));
if (index > -1) {
return this.users[this.users.length > index + 2
? index + 1 : 0].id;
} else {
return id || 0;
}}
HTML:
<button class="next-user" [routerLink]="['details', userService.getNextId(user.id)]" routerLinkActive="active">
Next User
</button>
DetailsListComponent:
private userService: UserService,
private activeRoute: ActivatedRoute,
private location: Location,
private router: Router) {
activeRoute.params.subscribe(params => {
this.detail = params['details'] === 'details';
let id = params['id'];
if (id !== null) {
Object.assign(this.user, userService.getNextId(id));
}
});
}
detail: boolean = true;
I searched the Internet and here the answer to this question, but found only suitable for php. Please, help me. What am I doing wrong? I just recently began to study angular 7 and do not always understand what to do.
I do not know how to explain it correctly, how to explain my problem. But I will try, I have a page that displays a list of my users. Clicking on the user opens a new page with more detailed information about it. In order not to go back to the page with a list of users and not to select the next user, a page with detailed information about the user assumes the presence of the Next button. When I click on this button, the array is iterated, it is determined by which ID the page is currently open and which ID is the next in this array, after which the page goes to the next ID. That is, the same page is opened, but the information on it is about another user who is following the list after the previous user.
But my button is currently not working and I do not understand why.
html angular typescript
I have a button that turns the pages. I need to remain in this component, change the ID in the address bar and thus I will change the information on the site. Data coming to me, look like this:
{
"users": [
{
"id": "3135",
"name": "Lulu"
},
{
"id": "8173",
"name": "Lala"
},
{
"id": "5783",
"name": "Lolo"
}
]
I am outputting detailed information about the user by getting an id. My navigation has looks like:
{ path: 'list', component: ListComponent },
{ path: '', redirectTo: '/list ', pathMatch: 'full' },
{ path: 'details/:id', component: DetailComponent }
I have a button, by pressing which the transition from '/details/Id' to 'details/nextId'. But this button does not work. This is a request for the next ID in the service. (I get the data from Database API)
private users: User = new Array<User>();
private locator = (u: User, id: number) => u.id === id;
getNextId(id: number): number {
let index = this.users.findIndex(u => this.locator(u, id));
if (index > -1) {
return this.users[this.users.length > index + 2
? index + 1 : 0].id;
} else {
return id || 0;
}}
HTML:
<button class="next-user" [routerLink]="['details', userService.getNextId(user.id)]" routerLinkActive="active">
Next User
</button>
DetailsListComponent:
private userService: UserService,
private activeRoute: ActivatedRoute,
private location: Location,
private router: Router) {
activeRoute.params.subscribe(params => {
this.detail = params['details'] === 'details';
let id = params['id'];
if (id !== null) {
Object.assign(this.user, userService.getNextId(id));
}
});
}
detail: boolean = true;
I searched the Internet and here the answer to this question, but found only suitable for php. Please, help me. What am I doing wrong? I just recently began to study angular 7 and do not always understand what to do.
I do not know how to explain it correctly, how to explain my problem. But I will try, I have a page that displays a list of my users. Clicking on the user opens a new page with more detailed information about it. In order not to go back to the page with a list of users and not to select the next user, a page with detailed information about the user assumes the presence of the Next button. When I click on this button, the array is iterated, it is determined by which ID the page is currently open and which ID is the next in this array, after which the page goes to the next ID. That is, the same page is opened, but the information on it is about another user who is following the list after the previous user.
But my button is currently not working and I do not understand why.
html angular typescript
html angular typescript
edited Nov 21 '18 at 14:13
LillyZhuk
asked Nov 21 '18 at 12:54
LillyZhukLillyZhuk
63
63
1
Can you post your html
– programoholic
Nov 21 '18 at 12:59
Can you please specify what exactly you mean by doesn't work? Is there some error or wrong id, etc?
– Daniil Andreyevich Baunov
Nov 21 '18 at 13:00
There are no errors in the IDE terminal or the console. How many do not press the button, nothing changes.
– LillyZhuk
Nov 21 '18 at 13:22
Thanks for clarification. I updated the answer have a look.
– Daniil Andreyevich Baunov
Nov 21 '18 at 16:00
@LillyZhuk did you try ?
– programoholic
Nov 22 '18 at 8:47
add a comment |
1
Can you post your html
– programoholic
Nov 21 '18 at 12:59
Can you please specify what exactly you mean by doesn't work? Is there some error or wrong id, etc?
– Daniil Andreyevich Baunov
Nov 21 '18 at 13:00
There are no errors in the IDE terminal or the console. How many do not press the button, nothing changes.
– LillyZhuk
Nov 21 '18 at 13:22
Thanks for clarification. I updated the answer have a look.
– Daniil Andreyevich Baunov
Nov 21 '18 at 16:00
@LillyZhuk did you try ?
– programoholic
Nov 22 '18 at 8:47
1
1
Can you post your html
– programoholic
Nov 21 '18 at 12:59
Can you post your html
– programoholic
Nov 21 '18 at 12:59
Can you please specify what exactly you mean by doesn't work? Is there some error or wrong id, etc?
– Daniil Andreyevich Baunov
Nov 21 '18 at 13:00
Can you please specify what exactly you mean by doesn't work? Is there some error or wrong id, etc?
– Daniil Andreyevich Baunov
Nov 21 '18 at 13:00
There are no errors in the IDE terminal or the console. How many do not press the button, nothing changes.
– LillyZhuk
Nov 21 '18 at 13:22
There are no errors in the IDE terminal or the console. How many do not press the button, nothing changes.
– LillyZhuk
Nov 21 '18 at 13:22
Thanks for clarification. I updated the answer have a look.
– Daniil Andreyevich Baunov
Nov 21 '18 at 16:00
Thanks for clarification. I updated the answer have a look.
– Daniil Andreyevich Baunov
Nov 21 '18 at 16:00
@LillyZhuk did you try ?
– programoholic
Nov 22 '18 at 8:47
@LillyZhuk did you try ?
– programoholic
Nov 22 '18 at 8:47
add a comment |
2 Answers
2
active
oldest
votes
I didn't understand what issue you are facing exactly but here is an overview of how you can route to next User id by clicking on button.
// in Component.ts file
// import Router from @angular/router
import { Router } from '@angular/router';
constructor(private _router: Router){}
// to get the next user id
getNextId(id: number): number {
// write your logic to get the next id here
}}
//navigate to user id
getNextUser(id:number){
let nextId = this.getNextId(id); // holds next id
this._router.navigate([`/register-step2/${nextId}`]);
}
<!-- In Component.html -->
<div class="userDetails">
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user" (click)="getNextUser(user.id)">
Next Movie
</button>
I assumed that for each userid service gets called and the result of the service is stored on user
variable. I Hope it helps .
add a comment |
=== EDIT (After the question was clarified) ===
Now I understand your use case. Here is how I would go about it.
Few things to note so that the example is clear:
list
route was renamed tousers
(makes more sense to me)- Brand new
UsersComponent
is created to handle all the users-related routes
DetailComponent
->UserDetailsComponent
ListComponent
->UsersListComponent
Those are just my coding conventions so that things are clear. You can leave your naming style.
In your root component, you will have your root <router-outlet>
. And you will also have another <router-outlet>
in UsersComponent
.
In your router settings you would have:
{ path: 'users', component: UsersComponent, children: [
{ path: '', component: UsersListComponent }
{ path: ':id', component: UserDetailsComponent }
] },
{ path: '', redirectTo: '/users ', pathMatch: 'full' }
Notice, I added a new component UsersComponent
which will be a parent for both UsersListComponent
and UserDetailsComponent
. It will hold a <router-outlet>
that will hold either UsersListComponent
or UserDetailsComponent
depending on the child route that is active.
- For
/users
it will renderUsersListComponent
. - For
/users/:id
it will renderUserDetailsComponent
.
So, UsersListComponent
will have something like the following template:
<div *ngFor="let user of users" class="user-list-item" >
<p>user.name</p>
<button class="open-user-details"
[routerLink]="['/users', user.id]">
Navigate To Details
</button>
</div>
In UserDetailsComponent
you will have something like the following:
<div class="userDetails">
<p> {{user.id}} </p>
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user"
[routerLink]="['/users', getNextUserId()]"
routerLinkActive="active">
Next User
</button>
And in .ts
file for UserDetailsComponent
you would have:
user: User; // complete user details object. ID included
constructor(private userService: UserService,
private activeRoute: ActivatedRoute)
// gets the next user id based on the current user.id
public getNextUserId(): number {
return this.userService.getNextId(this.user.id)
}
public ngOnInit(): void {
this.activeRoute.params.pipe(switchMap((params) => {
return this.userService.getUserById(params.id);
})).subscribe(user => {
this.user = user;
});
}
I assume your UserService
has separate methods:
getNextId(curId: number): number
getUserById(userId: number): Observable<User>
I have separate methods:
– LillyZhuk
Nov 26 '18 at 8:35
1
1.getNextId(id: number): number { let index = this.users.findIndex(user => user.id === id); if (index > -1) { return this.users[this.users.length > index + 2 ? index + 1 : 0].id; } else { return id || 0; } }
2.getUserById(id: number): Observable<User> { return this.getUsers() .pipe( map(users => users.find(user => user.id === id))); }
I used your code, but an error occurred error TS2322: Type 'Observable<User>' is not assignable to type 'User'. Property 'page' is missing in type 'Observable<User>'.
– LillyZhuk
Nov 26 '18 at 8:42
Yeah, you are right. sincegetUserById
returns an Observable, you should useswitchMap
here. To switch fromparams
Observable toUser
Observable. I updated the answer.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:09
Next time make sure you give all the necessary information straight away, though.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:11
It doesn't work((( ERROR TypeError: Cannot read property 'id' of undefined
– LillyZhuk
Nov 26 '18 at 12:39
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53412500%2fhow-to-get-the-next-id-from-the-array-when-paging%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I didn't understand what issue you are facing exactly but here is an overview of how you can route to next User id by clicking on button.
// in Component.ts file
// import Router from @angular/router
import { Router } from '@angular/router';
constructor(private _router: Router){}
// to get the next user id
getNextId(id: number): number {
// write your logic to get the next id here
}}
//navigate to user id
getNextUser(id:number){
let nextId = this.getNextId(id); // holds next id
this._router.navigate([`/register-step2/${nextId}`]);
}
<!-- In Component.html -->
<div class="userDetails">
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user" (click)="getNextUser(user.id)">
Next Movie
</button>
I assumed that for each userid service gets called and the result of the service is stored on user
variable. I Hope it helps .
add a comment |
I didn't understand what issue you are facing exactly but here is an overview of how you can route to next User id by clicking on button.
// in Component.ts file
// import Router from @angular/router
import { Router } from '@angular/router';
constructor(private _router: Router){}
// to get the next user id
getNextId(id: number): number {
// write your logic to get the next id here
}}
//navigate to user id
getNextUser(id:number){
let nextId = this.getNextId(id); // holds next id
this._router.navigate([`/register-step2/${nextId}`]);
}
<!-- In Component.html -->
<div class="userDetails">
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user" (click)="getNextUser(user.id)">
Next Movie
</button>
I assumed that for each userid service gets called and the result of the service is stored on user
variable. I Hope it helps .
add a comment |
I didn't understand what issue you are facing exactly but here is an overview of how you can route to next User id by clicking on button.
// in Component.ts file
// import Router from @angular/router
import { Router } from '@angular/router';
constructor(private _router: Router){}
// to get the next user id
getNextId(id: number): number {
// write your logic to get the next id here
}}
//navigate to user id
getNextUser(id:number){
let nextId = this.getNextId(id); // holds next id
this._router.navigate([`/register-step2/${nextId}`]);
}
<!-- In Component.html -->
<div class="userDetails">
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user" (click)="getNextUser(user.id)">
Next Movie
</button>
I assumed that for each userid service gets called and the result of the service is stored on user
variable. I Hope it helps .
I didn't understand what issue you are facing exactly but here is an overview of how you can route to next User id by clicking on button.
// in Component.ts file
// import Router from @angular/router
import { Router } from '@angular/router';
constructor(private _router: Router){}
// to get the next user id
getNextId(id: number): number {
// write your logic to get the next id here
}}
//navigate to user id
getNextUser(id:number){
let nextId = this.getNextId(id); // holds next id
this._router.navigate([`/register-step2/${nextId}`]);
}
<!-- In Component.html -->
<div class="userDetails">
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user" (click)="getNextUser(user.id)">
Next Movie
</button>
I assumed that for each userid service gets called and the result of the service is stored on user
variable. I Hope it helps .
// in Component.ts file
// import Router from @angular/router
import { Router } from '@angular/router';
constructor(private _router: Router){}
// to get the next user id
getNextId(id: number): number {
// write your logic to get the next id here
}}
//navigate to user id
getNextUser(id:number){
let nextId = this.getNextId(id); // holds next id
this._router.navigate([`/register-step2/${nextId}`]);
}
<!-- In Component.html -->
<div class="userDetails">
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user" (click)="getNextUser(user.id)">
Next Movie
</button>
// in Component.ts file
// import Router from @angular/router
import { Router } from '@angular/router';
constructor(private _router: Router){}
// to get the next user id
getNextId(id: number): number {
// write your logic to get the next id here
}}
//navigate to user id
getNextUser(id:number){
let nextId = this.getNextId(id); // holds next id
this._router.navigate([`/register-step2/${nextId}`]);
}
<!-- In Component.html -->
<div class="userDetails">
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user" (click)="getNextUser(user.id)">
Next Movie
</button>
answered Nov 21 '18 at 13:50
programoholicprogramoholic
3421424
3421424
add a comment |
add a comment |
=== EDIT (After the question was clarified) ===
Now I understand your use case. Here is how I would go about it.
Few things to note so that the example is clear:
list
route was renamed tousers
(makes more sense to me)- Brand new
UsersComponent
is created to handle all the users-related routes
DetailComponent
->UserDetailsComponent
ListComponent
->UsersListComponent
Those are just my coding conventions so that things are clear. You can leave your naming style.
In your root component, you will have your root <router-outlet>
. And you will also have another <router-outlet>
in UsersComponent
.
In your router settings you would have:
{ path: 'users', component: UsersComponent, children: [
{ path: '', component: UsersListComponent }
{ path: ':id', component: UserDetailsComponent }
] },
{ path: '', redirectTo: '/users ', pathMatch: 'full' }
Notice, I added a new component UsersComponent
which will be a parent for both UsersListComponent
and UserDetailsComponent
. It will hold a <router-outlet>
that will hold either UsersListComponent
or UserDetailsComponent
depending on the child route that is active.
- For
/users
it will renderUsersListComponent
. - For
/users/:id
it will renderUserDetailsComponent
.
So, UsersListComponent
will have something like the following template:
<div *ngFor="let user of users" class="user-list-item" >
<p>user.name</p>
<button class="open-user-details"
[routerLink]="['/users', user.id]">
Navigate To Details
</button>
</div>
In UserDetailsComponent
you will have something like the following:
<div class="userDetails">
<p> {{user.id}} </p>
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user"
[routerLink]="['/users', getNextUserId()]"
routerLinkActive="active">
Next User
</button>
And in .ts
file for UserDetailsComponent
you would have:
user: User; // complete user details object. ID included
constructor(private userService: UserService,
private activeRoute: ActivatedRoute)
// gets the next user id based on the current user.id
public getNextUserId(): number {
return this.userService.getNextId(this.user.id)
}
public ngOnInit(): void {
this.activeRoute.params.pipe(switchMap((params) => {
return this.userService.getUserById(params.id);
})).subscribe(user => {
this.user = user;
});
}
I assume your UserService
has separate methods:
getNextId(curId: number): number
getUserById(userId: number): Observable<User>
I have separate methods:
– LillyZhuk
Nov 26 '18 at 8:35
1
1.getNextId(id: number): number { let index = this.users.findIndex(user => user.id === id); if (index > -1) { return this.users[this.users.length > index + 2 ? index + 1 : 0].id; } else { return id || 0; } }
2.getUserById(id: number): Observable<User> { return this.getUsers() .pipe( map(users => users.find(user => user.id === id))); }
I used your code, but an error occurred error TS2322: Type 'Observable<User>' is not assignable to type 'User'. Property 'page' is missing in type 'Observable<User>'.
– LillyZhuk
Nov 26 '18 at 8:42
Yeah, you are right. sincegetUserById
returns an Observable, you should useswitchMap
here. To switch fromparams
Observable toUser
Observable. I updated the answer.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:09
Next time make sure you give all the necessary information straight away, though.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:11
It doesn't work((( ERROR TypeError: Cannot read property 'id' of undefined
– LillyZhuk
Nov 26 '18 at 12:39
|
show 1 more comment
=== EDIT (After the question was clarified) ===
Now I understand your use case. Here is how I would go about it.
Few things to note so that the example is clear:
list
route was renamed tousers
(makes more sense to me)- Brand new
UsersComponent
is created to handle all the users-related routes
DetailComponent
->UserDetailsComponent
ListComponent
->UsersListComponent
Those are just my coding conventions so that things are clear. You can leave your naming style.
In your root component, you will have your root <router-outlet>
. And you will also have another <router-outlet>
in UsersComponent
.
In your router settings you would have:
{ path: 'users', component: UsersComponent, children: [
{ path: '', component: UsersListComponent }
{ path: ':id', component: UserDetailsComponent }
] },
{ path: '', redirectTo: '/users ', pathMatch: 'full' }
Notice, I added a new component UsersComponent
which will be a parent for both UsersListComponent
and UserDetailsComponent
. It will hold a <router-outlet>
that will hold either UsersListComponent
or UserDetailsComponent
depending on the child route that is active.
- For
/users
it will renderUsersListComponent
. - For
/users/:id
it will renderUserDetailsComponent
.
So, UsersListComponent
will have something like the following template:
<div *ngFor="let user of users" class="user-list-item" >
<p>user.name</p>
<button class="open-user-details"
[routerLink]="['/users', user.id]">
Navigate To Details
</button>
</div>
In UserDetailsComponent
you will have something like the following:
<div class="userDetails">
<p> {{user.id}} </p>
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user"
[routerLink]="['/users', getNextUserId()]"
routerLinkActive="active">
Next User
</button>
And in .ts
file for UserDetailsComponent
you would have:
user: User; // complete user details object. ID included
constructor(private userService: UserService,
private activeRoute: ActivatedRoute)
// gets the next user id based on the current user.id
public getNextUserId(): number {
return this.userService.getNextId(this.user.id)
}
public ngOnInit(): void {
this.activeRoute.params.pipe(switchMap((params) => {
return this.userService.getUserById(params.id);
})).subscribe(user => {
this.user = user;
});
}
I assume your UserService
has separate methods:
getNextId(curId: number): number
getUserById(userId: number): Observable<User>
I have separate methods:
– LillyZhuk
Nov 26 '18 at 8:35
1
1.getNextId(id: number): number { let index = this.users.findIndex(user => user.id === id); if (index > -1) { return this.users[this.users.length > index + 2 ? index + 1 : 0].id; } else { return id || 0; } }
2.getUserById(id: number): Observable<User> { return this.getUsers() .pipe( map(users => users.find(user => user.id === id))); }
I used your code, but an error occurred error TS2322: Type 'Observable<User>' is not assignable to type 'User'. Property 'page' is missing in type 'Observable<User>'.
– LillyZhuk
Nov 26 '18 at 8:42
Yeah, you are right. sincegetUserById
returns an Observable, you should useswitchMap
here. To switch fromparams
Observable toUser
Observable. I updated the answer.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:09
Next time make sure you give all the necessary information straight away, though.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:11
It doesn't work((( ERROR TypeError: Cannot read property 'id' of undefined
– LillyZhuk
Nov 26 '18 at 12:39
|
show 1 more comment
=== EDIT (After the question was clarified) ===
Now I understand your use case. Here is how I would go about it.
Few things to note so that the example is clear:
list
route was renamed tousers
(makes more sense to me)- Brand new
UsersComponent
is created to handle all the users-related routes
DetailComponent
->UserDetailsComponent
ListComponent
->UsersListComponent
Those are just my coding conventions so that things are clear. You can leave your naming style.
In your root component, you will have your root <router-outlet>
. And you will also have another <router-outlet>
in UsersComponent
.
In your router settings you would have:
{ path: 'users', component: UsersComponent, children: [
{ path: '', component: UsersListComponent }
{ path: ':id', component: UserDetailsComponent }
] },
{ path: '', redirectTo: '/users ', pathMatch: 'full' }
Notice, I added a new component UsersComponent
which will be a parent for both UsersListComponent
and UserDetailsComponent
. It will hold a <router-outlet>
that will hold either UsersListComponent
or UserDetailsComponent
depending on the child route that is active.
- For
/users
it will renderUsersListComponent
. - For
/users/:id
it will renderUserDetailsComponent
.
So, UsersListComponent
will have something like the following template:
<div *ngFor="let user of users" class="user-list-item" >
<p>user.name</p>
<button class="open-user-details"
[routerLink]="['/users', user.id]">
Navigate To Details
</button>
</div>
In UserDetailsComponent
you will have something like the following:
<div class="userDetails">
<p> {{user.id}} </p>
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user"
[routerLink]="['/users', getNextUserId()]"
routerLinkActive="active">
Next User
</button>
And in .ts
file for UserDetailsComponent
you would have:
user: User; // complete user details object. ID included
constructor(private userService: UserService,
private activeRoute: ActivatedRoute)
// gets the next user id based on the current user.id
public getNextUserId(): number {
return this.userService.getNextId(this.user.id)
}
public ngOnInit(): void {
this.activeRoute.params.pipe(switchMap((params) => {
return this.userService.getUserById(params.id);
})).subscribe(user => {
this.user = user;
});
}
I assume your UserService
has separate methods:
getNextId(curId: number): number
getUserById(userId: number): Observable<User>
=== EDIT (After the question was clarified) ===
Now I understand your use case. Here is how I would go about it.
Few things to note so that the example is clear:
list
route was renamed tousers
(makes more sense to me)- Brand new
UsersComponent
is created to handle all the users-related routes
DetailComponent
->UserDetailsComponent
ListComponent
->UsersListComponent
Those are just my coding conventions so that things are clear. You can leave your naming style.
In your root component, you will have your root <router-outlet>
. And you will also have another <router-outlet>
in UsersComponent
.
In your router settings you would have:
{ path: 'users', component: UsersComponent, children: [
{ path: '', component: UsersListComponent }
{ path: ':id', component: UserDetailsComponent }
] },
{ path: '', redirectTo: '/users ', pathMatch: 'full' }
Notice, I added a new component UsersComponent
which will be a parent for both UsersListComponent
and UserDetailsComponent
. It will hold a <router-outlet>
that will hold either UsersListComponent
or UserDetailsComponent
depending on the child route that is active.
- For
/users
it will renderUsersListComponent
. - For
/users/:id
it will renderUserDetailsComponent
.
So, UsersListComponent
will have something like the following template:
<div *ngFor="let user of users" class="user-list-item" >
<p>user.name</p>
<button class="open-user-details"
[routerLink]="['/users', user.id]">
Navigate To Details
</button>
</div>
In UserDetailsComponent
you will have something like the following:
<div class="userDetails">
<p> {{user.id}} </p>
<p> {{user.name}} </p>
<p> {{user.age}} </p>
<p> {{user.occuption}} </p>
</div>
<button class="next-user"
[routerLink]="['/users', getNextUserId()]"
routerLinkActive="active">
Next User
</button>
And in .ts
file for UserDetailsComponent
you would have:
user: User; // complete user details object. ID included
constructor(private userService: UserService,
private activeRoute: ActivatedRoute)
// gets the next user id based on the current user.id
public getNextUserId(): number {
return this.userService.getNextId(this.user.id)
}
public ngOnInit(): void {
this.activeRoute.params.pipe(switchMap((params) => {
return this.userService.getUserById(params.id);
})).subscribe(user => {
this.user = user;
});
}
I assume your UserService
has separate methods:
getNextId(curId: number): number
getUserById(userId: number): Observable<User>
edited Nov 26 '18 at 10:08
answered Nov 21 '18 at 13:52
Daniil Andreyevich BaunovDaniil Andreyevich Baunov
1,042527
1,042527
I have separate methods:
– LillyZhuk
Nov 26 '18 at 8:35
1
1.getNextId(id: number): number { let index = this.users.findIndex(user => user.id === id); if (index > -1) { return this.users[this.users.length > index + 2 ? index + 1 : 0].id; } else { return id || 0; } }
2.getUserById(id: number): Observable<User> { return this.getUsers() .pipe( map(users => users.find(user => user.id === id))); }
I used your code, but an error occurred error TS2322: Type 'Observable<User>' is not assignable to type 'User'. Property 'page' is missing in type 'Observable<User>'.
– LillyZhuk
Nov 26 '18 at 8:42
Yeah, you are right. sincegetUserById
returns an Observable, you should useswitchMap
here. To switch fromparams
Observable toUser
Observable. I updated the answer.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:09
Next time make sure you give all the necessary information straight away, though.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:11
It doesn't work((( ERROR TypeError: Cannot read property 'id' of undefined
– LillyZhuk
Nov 26 '18 at 12:39
|
show 1 more comment
I have separate methods:
– LillyZhuk
Nov 26 '18 at 8:35
1
1.getNextId(id: number): number { let index = this.users.findIndex(user => user.id === id); if (index > -1) { return this.users[this.users.length > index + 2 ? index + 1 : 0].id; } else { return id || 0; } }
2.getUserById(id: number): Observable<User> { return this.getUsers() .pipe( map(users => users.find(user => user.id === id))); }
I used your code, but an error occurred error TS2322: Type 'Observable<User>' is not assignable to type 'User'. Property 'page' is missing in type 'Observable<User>'.
– LillyZhuk
Nov 26 '18 at 8:42
Yeah, you are right. sincegetUserById
returns an Observable, you should useswitchMap
here. To switch fromparams
Observable toUser
Observable. I updated the answer.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:09
Next time make sure you give all the necessary information straight away, though.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:11
It doesn't work((( ERROR TypeError: Cannot read property 'id' of undefined
– LillyZhuk
Nov 26 '18 at 12:39
I have separate methods:
– LillyZhuk
Nov 26 '18 at 8:35
I have separate methods:
– LillyZhuk
Nov 26 '18 at 8:35
1
1
1.
getNextId(id: number): number { let index = this.users.findIndex(user => user.id === id); if (index > -1) { return this.users[this.users.length > index + 2 ? index + 1 : 0].id; } else { return id || 0; } }
2. getUserById(id: number): Observable<User> { return this.getUsers() .pipe( map(users => users.find(user => user.id === id))); }
I used your code, but an error occurred error TS2322: Type 'Observable<User>' is not assignable to type 'User'. Property 'page' is missing in type 'Observable<User>'.– LillyZhuk
Nov 26 '18 at 8:42
1.
getNextId(id: number): number { let index = this.users.findIndex(user => user.id === id); if (index > -1) { return this.users[this.users.length > index + 2 ? index + 1 : 0].id; } else { return id || 0; } }
2. getUserById(id: number): Observable<User> { return this.getUsers() .pipe( map(users => users.find(user => user.id === id))); }
I used your code, but an error occurred error TS2322: Type 'Observable<User>' is not assignable to type 'User'. Property 'page' is missing in type 'Observable<User>'.– LillyZhuk
Nov 26 '18 at 8:42
Yeah, you are right. since
getUserById
returns an Observable, you should use switchMap
here. To switch from params
Observable to User
Observable. I updated the answer.– Daniil Andreyevich Baunov
Nov 26 '18 at 10:09
Yeah, you are right. since
getUserById
returns an Observable, you should use switchMap
here. To switch from params
Observable to User
Observable. I updated the answer.– Daniil Andreyevich Baunov
Nov 26 '18 at 10:09
Next time make sure you give all the necessary information straight away, though.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:11
Next time make sure you give all the necessary information straight away, though.
– Daniil Andreyevich Baunov
Nov 26 '18 at 10:11
It doesn't work((( ERROR TypeError: Cannot read property 'id' of undefined
– LillyZhuk
Nov 26 '18 at 12:39
It doesn't work((( ERROR TypeError: Cannot read property 'id' of undefined
– LillyZhuk
Nov 26 '18 at 12:39
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53412500%2fhow-to-get-the-next-id-from-the-array-when-paging%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Can you post your html
– programoholic
Nov 21 '18 at 12:59
Can you please specify what exactly you mean by doesn't work? Is there some error or wrong id, etc?
– Daniil Andreyevich Baunov
Nov 21 '18 at 13:00
There are no errors in the IDE terminal or the console. How many do not press the button, nothing changes.
– LillyZhuk
Nov 21 '18 at 13:22
Thanks for clarification. I updated the answer have a look.
– Daniil Andreyevich Baunov
Nov 21 '18 at 16:00
@LillyZhuk did you try ?
– programoholic
Nov 22 '18 at 8:47