Creating a model for a json - json

I'm trying to build a Azure cognitive text translator app in angular. Initially I need to load the supported languages. But when I use this link https://api.cognitive.microsofttranslator.com/languages?api-version=3.0. I'm getting response like this
"translation": {
"af": {
"name": "Afrikaans",
"nativeName": "Afrikaans",
"dir": "ltr"
},
"ar": {
"name": "Arabic",
"nativeName": "العربية",
"dir": "rtl"
},
"bg": {
"name": "Bulgarian",
"nativeName": "Български",
"dir": "ltr"
},
...
}
How to create a model that holds this type of json?
When I tried json2ts.com for building the model, it creates object for each language like
export interface Af {
name: string;
nativeName: string;
dir: string;
}
export interface Ar {
name: string;
nativeName: string;
dir: string;
}
export interface Bg {
name: string;
nativeName: string;
dir: string;
}
export interface Translation {
af: Af;
ar: Ar;
bg: Bg;
}
Do I need to create interface for all the available languages?
are there any other simple way to handle this?

The translation property of that object is a key-value map.
You could model the whole thing as follows:
type Dir = "ltr" | "rtl";
interface Translation {
name:string;
nativeName:string;
dir: Dir;
}
interface LangResponse {
translation: {[langCode:string]: Translation};
}

You could define a Typescript interface modeling the JSON data.
export interface LanguageInfo {
name: string
nativeName: string
dir: string
code?: string
toScripts?: Array<LanguageInfo>
}
export interface TranslationLanguages {
langCode: string
info: LanguageInfo
}
function fromJSON(json_data: string | Object): TranslationLanguages {
let obj: TranslationLanguages;
if (typeof json_data === "object") {
obj = json_data as TranslationLanguages;
} else {
obj = JSON.parse(json_data);
}
return obj;
}

Related

How to create TypeScript class from Json data? [duplicate]

This question already has answers here:
How do I cast a JSON Object to a TypeScript class?
(28 answers)
How to parse a JSON object to a TypeScript Object
(11 answers)
How do I initialize a TypeScript Object with a JSON-Object?
(18 answers)
Closed 1 year ago.
I'm using Angular to call an external API. Json data is in format like:
[
{
"AccessGroupsIdList": [],
"FirstName": "Greg",
"LastName": "Tipton",
"LocationIdList": [],
"PermissionProfile": {
"Name": "Agent",
"PermissionProfileId": {
"ID": "xy678219-bd7c-103d-b56b-1f1234a85990"
},
"Type": 3
},
"ManagerName": "Gilchrist, George",
"Status": true,
"UserGroupID": {
"ID": "00000000-0000-0000-0000-000000000000"
},
"UserGroupName": "ROOT",
"UserId": {
"ID": "4445cc66-819a-4da0-8fbf-d0bb8ce65941"
}
}
]
How do I create a class in typescript to read it since json data is nested?
export class Employees
{
AccessGroupsIdList: string[];
FirstName: string;
LastName: string;
LocationIdList : number[];
PermissionProfile ??
ManagerName: string;
Status: boolean;
UserGroupID ??
UserGroupName : string;
UserId ??
}
Please guide if the PermissionProfile, PermissionProfile will be separate nested classes?
How do I declare those?
To extend Andrew Halil's answer, I would use interfaces instead of classes in your definitions, since there do not appear to be any class methods involved; you are just describing the shape of a JSON object returned from a server
export interface Employee
{
AccessGroupsIdList: string[];
FirstName: string;
LastName: string;
LocationIdList : number[];
PermissionProfile: PermissionProfile;
ManagerName: string;
Status: boolean;
UserGroupId: ID;
UserGroupName : string;
UserId: ID;
}
export interface PermissionProfile
{
name: string;
permissionProfileId: ID;
type: string;
}
export interface ID
{
id: string;
}
Now as for an implementation, I don't use Angular all that much but you would do something like this to get the items typed
async function listEmployees(): Promise<Employee[]> {
// Make a fetch call to the API endpoint
const data = await fetch('https://some-api-endpoint.web/employees')
// if the response comes back ok, return the JSON-ified response.
.then(res => {
if(res.ok) return res.json()
return [];
});
// Instruct typescript that "data" is to be treated as an array of Employee elements.
return data as Employee[]
}
Try declaring the Typescript class structures as follows:
export class Employees
{
AccessGroupsIdList: string[];
FirstName: string;
LastName: string;
LocationIdList : number[];
PermissionProfile: PermissionProfile;
ManagerName: string;
Status: boolean;
UserGroupId: UserGroupID;
UserGroupName : string;
UserId: UserID;
}
export class PermissionProfile
{
name: string;
permissionProfileId: PermissionProfileID;
type: string;
}
export class PermissionProfileID
{
id: string;
}
export class UserGroupID
{
id: string;
}
export class UserID
{
id: string;
}
I would suggest to name the property names consistently with an Id (e.g. with UserGroupId). The name and type class property names are valid in TypeScript (unlike with the C# syntax).

Typescript JSON to interface dynamically

I'm pretty new to typescript and I want to turn the below JSON into an interface/type but the user1 key is dynamic and could be something different but the JSON inside the of key will be the same.
{
"code": 200,
"status": "success",
"data": {
"user1": {
"firstName": "John",
"lastName": "Smith",
"age": 25
}
}
}
I have the below so far. Is it possible to turn the data into a map in the Root interface as this is how I would do it in golang.
export interface Root {
code: number
status: string
data: Data
}
export interface Data {
[key: string]: User
}
export interface User {
firstName: string
lastName: string
age: number
}
export const sendRequest = (url: string): Root => {
const [data,setData]=useState([]);
const getData=()=>{
fetch(url
,{
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
)
.then(function(response){
return response.json();
})
.then(function(myJson) {
setData(myJson)
});
}
useEffect(()=>{
getData()
},[])
return JSON.parse(JSON.stringify(data));
}
const user = sendRequest(host + path)
console.log(user.data?.[0])
You can use index signatures:
export interface Root {
code: number
status: string
data: Data
}
export interface Data {
[key: string]: User
}
export interface User {
firstName: string
lastName: string
age: number
}

How to map JSON response to Model in Angular 4

I have tried a lot but I am not able to get endpoint response mapped to my model. I am using HttpClient and Angular4.
I got data back from service but it is not mapped correctly to my model class.
I have following JSON which service is Returning:
{
"result": [
{
"id": "1",
"type": "User",
"contactinfo": {
"zipcode": 1111,
"name": "username"
}
}
]
}
I have created a model in typescript which I will like to map to json response:
export interface result {
zipcode: number;
name: string;
}
This is how i call JSON endpoint.
result : string[] = [];
constructor(private http: HttpClient) { }
public getList(): result[] {
this.http.get<result[]>('url...', { headers: this.headers }).subscribe(
data => {
// 1. Data is returned - Working
console.log('data: ' + data);
this.result= data;
// This is the problem. My data is not mapped to my model. If I do following a null is returned
console.log('data mapped: ' + this.result[0].name);
},
(err: HttpErrorResponse) => {
// log error
}
);
return this.result;
}
You need to import the interface in your component,
import { result } from '.result';
Your interface should look like,
interface RootObject {
result: Result[];
}
interface Result {
id: string;
type: string;
contactinfo: Contactinfo;
}
interface Contactinfo {
zipcode: number;
name: string;
}
and change the type of result as,
result : result;
and assign the result as,
this.result = data;
You can use http://www.jsontots.com/ to create the interface based on JSON
your "data" is an Object, with a property "result". result[] has a property called "contactInfo". in contactInfo you have the data you want, so
//you have no model, so NOT get<result[]>
this.http.get('url...', { headers: this.headers }).subscribe(
data => {
this.result= data.result[0].contactInfo;
}

Angular2 & Typescript - Create object from nested JSON

I have a class which has multiple interfaces inside of it to model a JSON data. For example:
interface A {
id: number;
}
interface B {
name: string;
surname?: string;
}
class MyClass implements A {
people: B[];
notes: string[];
function1(){...}
function2(){...}
}
And I have a JSON in the same structure:
{
id: 1,
people: [
{
name: "john"
},
{
name: "alice",
surname: "smith"
}
],
notes: [ "Very important top secret note" ]
}
Can I create an instance of MyClass from this JSON directly?
Your data structure is almost the same as your class, you'd have to add an id property to the class
class MyClass implements A {
id: number;
// ....
}
The problem is if you were trying to do something like this:
let data: MyClass = {
id: 1,
people: [
{
name: "john"
},
{
name: "alice",
surname: "smith"
}
],
notes: [ "Very important top secret note" ]
}
This won't work because your json does not have the methods (function1, function2).
One solution would be to really instantiate the MyClass and pass the json, or have a constructor method for that like
class MyClass {
static createFrom(jsonData: A & B): MyClass {
// create the objct and return
}
}
Or, you could create a variable of that type by combining an existing instance of the class and spreading the json.
Like so:
let json = {
id: 1,
people: [
{
name: "john"
},
{
name: "alice",
surname: "smith"
}
],
notes: ["Very important top secret note"]
}
const c = new MyClass();
let mClass: MyClass = {...json, function1: c.function1, function2: c.function2 };
mClass.function1();
Link to playground

From JSON to Typescript interface

I'm going crazy.
I have this JSON:
{
'name': 'Help Me',
'filters': {
'filter1': {
'filter_id': 'wow',
'filter_query': 'maw',
},
'filter2': {
'filter_id': 'wow',
'filter_query': 'maw',
}
}
}
And i'm trying to get this in this way:
export interface MyObject {
name: string;
filters: Filters;
}
export interface Filters {
[key: string]: QueryFilter;
}
export interface QueryFilter {
filter_id: string;
filter_query: string;
friendly_filter_query: string;
}
Or in this way:
export interface MyObject {
name: string;
filters: Map<string, QueryFilter[]>;}
But in first case i got this error message:
Property 'filters' is missing in type '{ 'name': string; ...'.
And in the second case i got this:
Property 'clear' is missing in type '{ 'filter1': { 'filter_id': string; 'filter_query': string; }...'.
I really can't figure out.