I have been trying to validate the following data from a body.
I have schema that validates the properties like Account ID and Associate number and that is fine, but what I want to drill down on the validation.
This below is the console and body response
From }) I get the below:
(1) [{,,,}] (not sure if those are commas or periods)
(0): [{,,,}]
AccountID: xxxx,
AssociateNumber: xxxx,
AssociateType: "Account",
AccountType: "PRIVATE AVIA",
DisplayName: "Jet Masters Air",
Body Response
[
{
"AccountID": xxxx,
"AssociateNumber": xxxx,
"AssociateType": "Account",
"AccountType": "PRIVATE AVIA",
"DisplayName": "Jet Masters Air",
}
]
//Im trying the following:
pm.test("Verify the Role name ", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.property.items.DisplayName).to.eql("Jet Masters Air")
})
Resolution:
pm.test("Verify the Role name ", function () {
var jsonData = pm.response.json(); pm.expect(jsonData[0].DisplayName).to.eql("Jet Masters Air") })
Related
I have a json file that contains content for several different pages that are under a "service" category. I use dynamic routes in nextJS by having a file as "[serviceId].tsx", this routing works. However I have a json file where I want to use the [serviceId] provided in the route to access information.
I have the following code in my [serviceId].tsx file:
const json = jsonFile.services
const router = useRouter()
const serviceId = router.query.serviceId
return (
<div>
<ArticleWithPicture title={content.title} description={content.description}/>
</div>
)
}
My json file looks similar to this (ive edited it to be more clear for this example):
{
"serviceId":
[
{
"service1": {
"id": "xx",
"title": "xxx",
"description": "xx",
"featuredCompany":
[
{ "id": "1",
"name": "xxx",
"companyPageURL": "/",
"imagePath": "xxx",
"description": "xxx",
"additionalServices": {
"service1": "xxx",
"service2": "xxx"
},
"instagramURL":"/",
"twitterURL": "/"
}
]
}
},
{
"service2": {
"id": "xxx",
"title": "xxx",
"description": "xxx",
"featuredCompany":
[
{ "id": "1",
"name": "xxx",
"companyPageURL": "/",
"imagePath": "xxx",
"description": "xxx",
"additionalServices": {
"service1": "xxx",
"service2": "xx"
},
"instagramURL":"/",
"twitterURL": "/"
}
]
}
}
]
}
Basically, each Service has the content for each indiviual page. So I want to dynamically set for instance the title of my component "ArticleWithPicture" based on the corresponding title in my json file based on the serviceId that I get from router.query.serviceId. However when I try the following code:
<ArticleWithPicture title={json.{serviceId}.title}/>
I get error (this is due to how I use "{}" within a "{}", is there a way to do this better?
But I also cannot access it if I do eg:
const title = json.serviceId.title
or (what is what I actually want to do ie: query the json file based on my serviceId provided by "router.query.serviceId")
const title = json.{serviceId}.title
I guess something might be wrong with either my json file structure or how I try to access it. Any advice would be appreciated.
Thanks!
I'm assuming the JSON you provided is your entire jsonFile.
If the JSON you provided is just jsonFile.services, then change any uses of jsonFile to jsonFile.services
and update the type.
The format of the JSON isn't great for your use case because there's a lot of unnecessary wrapping.
With your current JSON
Assuming you cannot modify the format of the JSON, you would have to find the service from the serviceId array:
function getService(json, serviceId) {
return json.serviceId
.find((serviceWrapper) => serviceWrapper[serviceId] !== undefined)
?.service;
}
A fully typed example:
type Service = {
id: string
title: string
description: string
// ...
};
// you don't have to use this, I just included it for clarity
type JsonFile = {
serviceId: {
[serviceId: string]: Service
}[]
};
function getService(json: JsonFile, serviceId: string): Service | undefined {
return json.serviceId
.find((serviceWrapper) => serviceWrapper[serviceId] !== undefined)
?.service;
}
// declare const jsonFile: JsonFile;
export default function ServicePage() {
const router = useRouter();
const serviceId = router.query.serviceId as string;
const content = getService(jsonFile, serviceId);
if (!content) return (
<div>
{'Article doesn\'t exist.'}
</div>
);
return (
<div>
<ArticleWithPicture title={content.title} description={content.description} />
</div>
);
}
With better JSON
An example JSON that would need less unwrapping is:
{
"service1": {
"id": "xx",
"title": "xxx",
// ...
},
"service2": {
"id": "xxx",
"title": "xxx",
// ...
}
}
type JsonFile = {
[serviceId: string]: Service
}
Then you would be able to just do jsonFile[serviceId] or jsonFile.services[serviceId] to get a service.
I want to define a model class in angular8 for the below nested JSON response.
JSON Response:
{
"message": "All Users fetched",
"status": "Success",
"data": [
{
"userid": "abc22",
"password": "abc22",
"role": 1,
"sessionid": "AWS1",
"sessiontype": "RC01",
"status": null
}
]
}
I am not sure how to do it for the nested JSON response. Could someone help me with it.
Lets assume that all the datatypes of the above fields are String. Thanks in advance
I assume you often have the response with message and status fields, but that the structure of the data field is different for different requests. In that case, I'd recommend you do a generic interface like this:
export interface ApiResponse<T> {
message: string,
status: "Success" | "Error", // Add more possible status responses if needed
data: T
}
The user model would look something like this:
export interface User {
userId: string,
password: string,
role: number,
sessionid: string
sessiontype: string,
status: string // Or whatever type this should be
}
Now you can create a type alias like this:
type UserResponse = ApiResponse<User[]>
And use it with Angular's http service like this:
this.http.get<UserResponse>('/api/endpoint/to/userlist')
.subscribe(resp => {
console.log(resp.data) // This should print out the list of users
})
*Edit*
It should be noted that I'm using interfaces instead of classes, because that's usually what you want to do in angular. Interfaces don't generate any javascript code when compiled, they just help you with the typechecking during development. There will be no checking of the data structure during runtime, so if your response doesn't actually look like that you may run into problems.
You could do something like this:
class User {
userId: string;
password: string;
role: number;
sessionid: string;
sessiontype: string;
status: string;
}
class Response {
message: string;
status: string;
data: User[];
}
const jsonData = {
"message": "All Users fetched",
"status": "Success",
"data": [
{
"userid": "abc22",
"password": "abc22",
"role": 1,
"sessionid": "AWS1",
"sessiontype": "RC01",
"status": null
}
]
}
const response = new Response();
response.message = jsonData.message;
response.status = jsonData.status;
response.data = jsonData.data.map(userData => {
const user = new User();
user.userId = userData.userId;
});
I'm using express.js and sequelize.js to build an API. Once I retrieved an object from the DB using sequelize, I want to
filter out object attributes (e.g. retrieve the user, but don't render the User's password hash to the returned JSON)
add new object attributes
before I return it from the API as JSON.
Similar to what these Rails libraries do:
Roar
Grape Entity
What's the most common framework to do that in node? Or do sequelize.js / express.js contain functionality to do that?
UPDATE
Ok, there is a basic example, passport.js gets the authenticated user's object from the DB and attaches it to req.user;
router.get('/me/data',
passport.authenticate('bearer', { session: false }),
function(req, res) {
res.status(200).send(req.user);
}
);
That would return the following JSON response:
{
"id": 24,
"first_name": "John",
"last_name": "Doe",
"email": "mymail#example.com",
"password": "8d23cb9c4827bc06bb30ac47c06af0efbdbeb575001ab7de5387da4085f7184a381335c0f04b45f4a40e5a7042d47ae1e2d29d28fd5be1d534f09ba3db04e8ca",
"updatedAt": "2016-01-25T09:19:07.422Z",
"createdAt": "2016-01-25T09:19:07.422Z",
"data": null
}
But I want to return something like this:
{
"id": 24,
"full_name": "John Doe",
"email": "mymail#example.com",
"data": null
}
And not just for this one case, but in any case a user object is rendered.
The simplest solution would be to edit req.user before sending it:
function
render (user) {
callback({
"id": user.id,
"full_name": user.first_name + ' ' + user.last_name,
"email": user.email,
"data": null
});
}
router.get('/me/data',
passport.authenticate('bearer', { session: false }),
function(req, res) {
render(req.user, function(user) {
res.status(200).send(user);
});
}
);
This module will helper you with Grape Entity manner:
https://github.com/baijijs/entity
For example:
const Entity = require('baiji-entity');
const userEntity = new Entity({
id: true,
fullname: true,
email: true,
data: true
});
userEntity.parse(req.user);
// And the parsed result will be as below
{
"id": 24,
"full_name": "John Doe",
"email": "mymail#example.com",
"data": null
}
Hope this can help you.
Ok so you would like to chop of some of the fields? You could chop it of before the server is sending the response. For example with a module like this https://www.npmjs.com/package/json-chop or if you use mongo db you can hide the fields like described here https://docs.mongodb.org/manual/tutorial/project-fields-from-query-results/
Without knowing more details about the setup, the following (untested) code has the potential to work. You could specify the attributes field in your query against the model in order to filter out results (based on certain conditions):
router.get('me/data',function(req, res) {
db.UserModel.find({
attributes:['id','first_name','last_name','email','data'],
where: { id: req.user.id}, //put in here whatever you are using to get the info from the database
})
.then (function(user) {
var formatUser = {
id: user.id,
full_name: user.first_name + ' ' + user.last_name,
email: user.email,
data: user.data,
};
res.json(formatUser);
}
});
See the following docs for more information:
http://docs.sequelizejs.com/en/latest/docs/models-usage/
http://docs.sequelizejs.com/en/latest/docs/querying/
I receive the following error when I use Ember Data to create records from a JSON response. What gives? I am following what the docs state.
Uncaught Error: Assertion Failed: Ember Data expected a number or string to represent the record(s) in the `user` relationship instead it found an object. If this is a polymorphic relationship please specify a `type` key. If this is an embedded relationship please include the `DS.EmbeddedRecordsMixin` and specify the `user` property in your serializer's attrs object.
JSON being parsed:
[
{
"id": 76,
"title": "Title",
"shipped": 0,
"date": "2015-05-21T05:00:00.000Z",
"user": {
"firstName": "First Name",
"lastName": "Last Name",
"email": "hellothere#gmail.com",
"id": 1
}
}
]
Shipment Model:
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
user: DS.belongsTo('user', { async: false })
});
Route:
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel: function() {
if(!localStorage.accessToken) {
this.transitionTo('login');
}
},
model: function() {
var shipmentObjects = [];
var App = this;
Ember.$.getJSON('http://localhost:1337/subscription/1/shipments/upcoming', function(shipments) {
shipments.forEach(function(data) {
var shipment = App.store.push('shipment', data);
shipmentObjects.pushObject(shipment);
});
});
return shipmentObjects;
}
});
You can create a custom serializer, if you can't modify your json response and manage to arrange data in other way
App.MODELNAMESerializer = DS.ActiveModelSerializer.extend({
extract: function(store, type, payload, id, requestType){
var shipments = [];
//CREATE A NEW PAYLOAD THAT EMBER CAN READ
var _payload = { };
return this._super(store, type, _payload, id, requestType);
}
});
Your json should look something like this
{
shipments: [
{
"id": 76,
"title": "Title",
"shipped": 0,
"date": "2015-05-21T05:00:00.000Z",
"user_id": 1,
}
],
"users": [
{
"firstName": "First Name",
"lastName": "Last Name",
"email": "hellothere#gmail.com",
"id": 1
}
]
}
Read the error message. It could hardly be clearer. By default, Ember Data expects an association to be represented by an ID. If the association is instead embedded, you must tell Ember Data that. You'll need something like:
// serializers/shipment.js
export default ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
user: { embedded: 'always' }
}
});
And remove the {async: false}, since the data is embedded right there.
See http://emberjs.com/api/data/classes/DS.EmbeddedRecordsMixin.html.
I am new to node.js and using mongoose along with node.js.
Schema:
var userSchema = new mongoose.Schema({
username: String,
password: String,
phone_no : String,
email: String,
name:String,
dob: {type: Date, "default": Date.now},
city:String,
locality:{lattitude:Number,longitude:Number},
sports: [String]
});
sample entry:
"userId": 10,
"username": "shu",
"name": "shubham goyal",
"password": "ahu",
"phone_no": "919357701457",
"email": "shubham2892#gmail.com",
"city": "delhi",
"_id": {
"$oid": "5331dbc243bb59f80a7ed60b"
},
"sports": [
"cricket,football"
],
"dob": {
"$date": "2014-03-25T19:40:50.886Z"
},
"__v": 0
}
The query i am trying to make:
models.user.find({'sports' : sports_selected},function(err,users) {
if(err) {
console.log("Cannot fetch sports with requested username" + req.user.username);
console.log(err);
}if(!users){
console.log("cannot find specified username" + req.user.username);
}else{
console.log(users.username);
//sport = player.sports;
//sport = ['cricket','football','basketball'];
}
});
I am getting undefined in users.username.I want to return all users who have selected a particular sports say 'cricket'.I googled it a lot but could not find anything.
It looks like your sample entry is incorrectly formatted. Sports entry shouldn't be like this:
"sports": [
"cricket,football"
]
You should keep the sports data like this instead:
"sports": [
"cricket","football"
]
If you provide cricket and football in the same string, mongo cannot differentiate these two as different sports.
Also users should be an array, so you need to loop through the array. Say you have one user with sport selected as cricket, then you can print users[0].username