Angular convert json to array of object - arrays

I am getting the below JSON data from a rest web service. I am trying to figure out how I can convert to an array of object.
{
"John": "Buttler"
"Hugh": "Martin"
.
.
.
}
I am trying to convert to below object. Basically I am expecting Person[]. In above JSON, John, Hugh are first names and Buttler, Martin are last names.
export class Person{
firstName: string;
lastName: string;
}
I am able to convert if I get the json as below
[
{
"firstName": "John"
"lastName:: "Buttler"
},
{
"firstName": "Hugh"
"lastName:: "Martin"
}
]
Angular Service Code:
findAllPersons(): Observable<Person[]> {
return this.httpClient.get<Person[]>('url');
}

You have to process the recieved response in your required format.
findAllPersons(): Observable<Person[]> {
return this.httpClient.get<object>('url');
}
findAllPersons().subscribe((response) =>{
let array = [];
for(let key in response){
let p = new Person();
p.firstName = key;
p.lastName = response[key];
array.push(p);
}
console.log(array); // your required array
});

import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
interface NameData {
[firstName: string]: string;
}
interface Person {
firstName: string;
lastName: string;
}
#Injectable()
class PersonService {
constructor(private httpClient: HttpClient) {}
findAllPersons(): Observable<Person[]> {
return this.httpClient.get<NameData>('url').pipe(
map((v) =>
Object.entries(v).map(([firstName, lastName]) => ({
firstName,
lastName,
}))
)
);
}
}

Related

Get the foreign key in a httpRequest in nestJs

I'm trying to make many request in nestJs and specially some with the role of my users and i wanted to be able to list all users who match user.role = "Role's name" but i can't get the foreign key user from my table role.
My controller look like this and both of my entities reference each other as a role can have one or many user and a user one and only one role.
import { Controller, Get, Param, Post } from '#nestjs/common';
import { Body } from '#nestjs/common/decorators';
import { AuthDto } from 'src/authentification/auth.dto';
import { Role } from './role.entity';
import { User } from './user.entity';
import { UserService } from './user.service';
#Controller('user')
export class UserController {
constructor(private readonly UserService: UserService){}
#Get()
async getAllUser(): Promise<User[]>{
return this.UserService.getListUser();
}
#Get('/Role')
async getListRole(): Promise<Role[]> {
return this.UserService.getListRole();
}
#Get('/Role/:role')
async getUserByRole(#Param('role') role : number): Promise<User[]> {
return this.UserService.getUserByRole(+role);
}
#Get('/Pseudo/:pseudo')
async getUserByPseudo(#Param('pseudo') pseudo : string): Promise<User> {
return this.UserService.getUserByPseudo(pseudo);
}
#Get('/id/:id')
async getUserById(#Param('id') id : number): Promise<User> {
return this.UserService.getUserById(+id);
}
#Post('/New')
async createUser(#Body() user: AuthDto){
return this.UserService.createUser(user);
}
}
and here is the service
import { Get, Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { AuthDto } from 'src/authentification/auth.dto';
import { Repository } from 'typeorm';
import { Role } from './role.entity';
import { User } from './user.entity';
#Injectable()
export class UserService {
constructor(
#InjectRepository(User) private usersRepository: Repository<User>,
#InjectRepository(Role) private rolesRepository: Repository<Role>
){}
getUserById(id): Promise<User> {
return this.usersRepository.findOneOrFail(id);
}
getUserByPseudo(pseudo: string): Promise<User> {
return this.usersRepository.findOne({pseudo});
}
getListRole(): Promise<Role[]> {
return this.rolesRepository.find();
}
getListUser(): Promise<User[]> {
return this.usersRepository.find();
}
getUserByRole(role): Promise<User[]> {
return this.usersRepository.find({where: {role: role}});
}
createUser(data: AuthDto){
const user = {
pseudo: data.username,
password: data.password,
pointEffort: 10,
scienceTab: [],
inventaire: [],
technologieTab: [],
role: {
id: 1,
nom: "joueur",
users: []
},
};
const result = this.usersRepository.save(user);
return result;
}
}
user.entity.ts
import { Place } from "src/place/place.entity";
import { Science } from "src/science/science.entity";
import { TechnologieUser } from "src/technologie/technologieUser.entity";
import { Column, Entity, ManyToMany, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { Role } from "./role.entity";
#Entity()
export class User {
#PrimaryGeneratedColumn()
id: Number;
#Column()
pseudo: String;
#Column()
password: String;
#Column()
pointEffort: Number;
#ManyToOne(type => Role, role => role.users)
role: Role;
#ManyToMany(type => Science, science => science.users)
scienceTab: Science[];
#OneToMany(type => TechnologieUser, technologieUser => technologieUser.user)
technologieTab: TechnologieUser[];
#OneToMany(type => Place, place => place.user)
inventaire: Place[];
}
role.entity.ts
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { User } from "./user.entity";
#Entity()
export class Role {
#PrimaryGeneratedColumn()
id: Number;
#Column()
nom: String;
#OneToMany(type => User, user => user.role)
users: User[];
}
But when i use getListRole() i only get this
And so i don't have the list of my users returned in the property role.users which is missing.
So the question is : how can i have role.users added in the data of getListRole()?
Thx a lot
Get role id from params, then do, this.usersRepository.find({ relations: {Role: true}, where: { role: { id: roleId } } })

Property 'Choices' does not exist on type 'Promise<IFieldInfo>'

I have the following type script inside my ReactJs SPFx sharepoint online web part:-
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '#microsoft/sp-core-library';
import {
IPropertyPaneConfiguration,
IPropertyPaneDropdownOption,
PropertyPaneDropdown} from '#microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '#microsoft/sp-webpart-base';
import * as strings from 'ContactListWebPartStrings';
import ContactListApp from './components/ContactListApp';
import { IContactListProps } from './components/IContactListProps';
import { sp } from "#pnp/sp/presets/all";
export interface IContactListWebPartProps {
department: string;
}
export default class ContactListWebPart extends BaseClientSideWebPart<IContactListWebPartProps> {
private viewModeOptions: IPropertyPaneDropdownOption[] = null;
public render(): void {
const element: React.ReactElement<IContactListProps> = React.createElement(
ContactListApp,
{
department: this.properties.department,
context: this.context
}
);
ReactDom.render(element, this.domElement);
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
public onInit(): Promise<void> {
return super.onInit().then( _ => {
sp.setup({
spfxContext: this.context
});
const choice =
sp.web.lists.getByTitle('Contacts').fields.getByTitle('Department').get();
this.viewModeOptions = choice.Choices.map((choice: string, idx: number) =>
{
return {
key: idx,
text: choice
}
})
});
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneDropdown('department', {
label: 'Department',
options: this.viewModeOptions,
selectedKey: this.viewModeOptions[0].key,
disabled: !this.viewModeOptions
}),
]
}
]
}
]
};
}
}
but i am getting this error on choice.Choices.map:-
Property 'Choices' does not exist on type 'Promise'
Change this:
const choice = sp.web.lists.getByTitle('Contacts').fields.getByTitle('Department').get();
(In this case choice is just Promise, not returned value.)
For this:
const choice = await sp.web.lists.getByTitle('Contacts').fields.getByTitle('Department').get();
(In this case await cause to load data and choice contains value.)
With await inside function, you need to make it async like this:
return super.onInit().then(async _ => {

Selecting object from JSON array in Angular 4

working on an angular4 app that has 2 components/pages.
the first component is related to the object id:1 and it is one page and the second component is related to id:2 and it is another page. both of these pages share the same template 'page.component.html'
how do get the first component to only render the object with id:1? and the same for the second component. I understand that right now as it is set up, each component is going to both objects in the array.
is there a way i can do this in the service or each component?
data.json
[
{
"id": 1,
"array":
[
{
"name": "name1.a",
"title": "title1.a",
},
{
"name": "name1.b",
"title": "title1.b",
},
{
"name": "name1.c",
"title": "title1.c",
}
],
}
{
"id": 2,
"array":
[
{
"name": "name2",
"title": "title2",
}
]
}
]
page.component.html
<div *ngFor="let set of sets">
<p>{{set.name}}</p>
<p>{{set.title}}</p>
</div>
page.component.ts
// Imports
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { page } from '../page';
import { Observable } from 'rxjs/Rx';
// Import RxJs required methods
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
#Injectable()
export class GenreService {
// Resolve HTTP using the constructor
constructor (private http: Http) {}
private pagesUrl = '../assets/json/data.json';
// Fetch all existing comments
getPages() : Observable<Page[]>{
// ...using get request
return this.http.get(this.pagesUrl)
// ...and calling .json() on the response to return data
.map((res:Response) => res.json())
//...errors if any
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
}
page.ts
export class Page {
constructor(
public id: number,
public array: array,
public name: string,
public title: string
){}
}
page.component.ts
import { Component, OnInit } from '#angular/core';
import { Page } from './page';
import { PageService } from '../../services/page.service';
#Component({
selector: 'page1',
templateUrl: './page.component.html',
providers: [ PageService ],
})
export class Page1Component implements OnInit {
pages: Page[];
errorMessage: string;
ngOnInit() {
this.getPages();
}
getPages() {
this.genreService.getPages()
.subscribe(
pages => this.pages = pages,
error => this.errorMessage = <any>error);
}
}
This will work good with you
<div *ngFor="let set of sets.array">
<p>{{set.name}}</p>
<p>{{set.title}}</p>
</div>
Maybe you can change the method getPages() for getPage(id: number) and filter by id. It would be like so:
getPage(id: number) : Observable<Page>{
// ...using get request
return this.http.get(this.pagesUrl)
// ...and calling .json() on the response to return data
.map((res:Response) => res.json())
// ... do antoher map an return the correct object
.map((data: Array<any>) => {
return data.find(x => x.id === id)
})
//...errors if any
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
With that fucntion it will only return the Page that you want,
Hope that helps.

Search is not a function error on Angular 2 Pipe Array Filter

I have Angular 2 Search Pipe that filters against an array... Like this...
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'SearchPipe'
})
export class SearchPipe implements PipeTransform {
transform(value, args?): Array<any> {
let searchText = new RegExp(args, 'ig');
if (value) {
return value.filter(ocurrence => {
if ( ocurrence.nroCasoDegir ) {
return ocurrence.nroCasoDegir.search(searchText) !== -1;
}
});
}
}
}
But I always get the follow error...
ocurrence.nroCasoDegir.search is not a function
How can I solve it?
Thanks
This issue is just a typo, you meant indexOfnot search.
Try with this:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'SearchPipe'
})
export class SearchPipe implements PipeTransform {
transform(value, args?): Array<any> {
let searchText = new RegExp(args, 'ig');
if (value) {
return value.filter(ocurrence => {
if ( ocurrence.nroCasoDegir ) {
return ocurrence.nroCasoDegir.indexOf(searchText) !== -1;
}
});
}
}
}

Representing Mongoose model as a Typescript class

I'm writing a simple web application using Angular 2 written in TypeScript. MongoDB is my database on a Mongoose framework while running on a Node server on an Express framework. My MongoDB and Node code is written in vanilla JS.
Now, I created a Mongoose model for a Country as following:
"use strict";
const Schema = require('mongoose').Schema,
db = require('../../config/database');
let countrySchema = new Schema({
countryName: { type: String, index : { unique : true } }
});
let Country = db.model('Country', countrySchema);
module.exports = Country;
Now, Country is what I want my object to be. In my app component, I have:
import { Component } from '#angular/core';
import { CountryService } from '../services/country.service';
import { Country } from '../models/country.model';
#Component({
selector: 'my-app',
templateUrl: 'app/views/app.component.html',
providers: [ CountryService ]
})
export class AppComponent {
originCountries: Country[];
destinationCountries: Country[];
constructor(private countryService: CountryService) { };
ngOnInit() {
this.getCountries();
}
getCountries() {
this.countryService.getCountries()
.then(countries => {
this.originCountries = countries;
this.destinationCountries = countries;
});
}
}
See how originCountries and destinationCountries should be arrays of Countries? I can't just import Country from the Country model (even though it sounded right in my head at the time).
What is the best way to create a country class that is based on the Mongoose model?
You use an interface like this ICountry:
export interface ICountry {
_id: string;
name: string;
}
You can now use this interface in your mongoose setup:
import mongoose = require('mongoose');
import { ICountry } from './interfaces';
var _schema: mongoose.Schema = new mongoose.Schema({
name: { type: String, required: true, index: { unique: true } }
});
type CountryType = ICountry & mongoose.Document;
var _model = mongoose.model <CountryType> ('Country', _schema);
export class Country {
static getAll(): Promise<Array<ICountry>> {
return new Promise<ICountry> ((resolve, reject) => {
_model.find((err, counties) => {
err ? reject(err) : resolve(counties);
});
});
}
}
And the route setup:
var router = express.Router();
router.get('/api/countries', (req, res) => {
Country.getAll().then(c => {
return res.json(c);
});
});
And implement it in your Angular application, if you need some methods or just import the interface direct in your service class:
import { ICountry } from '../../interfaces';
...
countries: Array<ICountry>
This is how I do it in my project:
In my schema file:
///<reference path="../typings/mongoose/mongoose.d.ts"/>
import * as mongoose from 'mongoose';
var UserSchema = new mongoose.Schema({
name: String,
// ...
});
export interface IUser extends mongoose.Document {
_id: string;
name: string;
// ...
}
export interface IUserModel extends mongoose.Model<IUser> { }
export var User: IUserModel = <IUserModel>mongoose.model<IUser>('User', UserSchema);
In the server side code:
import {User, IUser, IUserModel} from '../schemas/user.schema';
// ...
User.findOne({ ... });
In the client side code I now can use the IUser interface:
import {IUser} from '../---/schemas/user.schema';
// ...
userCache: Array<IUser>;

Resources