Count objects in array in an object in Frisby - node.js

I am starting to learn FrisbyJS and trying to create some assertions.
I get an json that looks like this
[
{
"articles": [
{
"article": "123-123002",
"updated": "2016-10-20T14:57:25",
"sourced balance": [],
"balance": "50.00"
},
{
"article": "100-123001",
"updated": "2016-10-20T14:41:36",
"sourced balance": [],
"balance": "10.00"
}
],
"DistrictID": [],
"WarehouseID": "SebastiansWarehouse",
"SourceID": "1234",
"City": "Stockholm",
"WarehouseName": "Sebastians Warehouse",
"WarehouseType": "STORE"
}
]
And I want to:
1. count the number of article objects
2. verify that the number X in articles array has a variable with value "123-123002"
How can I do this in Frisby?
My code currently is:
var frisby = require('frisby');
frisby.create('Mekonomen RIF1')
.get('https://10.254.8.67:9443/INTERSHOP/rest/WFS/Mekonomen-MekB2BSE-Site/-/availability/sources/1234/warehouses/SebastiansWarehouse/products/',{ strictSSL: false})
.expectStatus(200)
.expectHeaderContains('content-type', 'application/json')
.expectJSON('?',{
articles: [],
DistrictID: [],
WarehouseID: "SebastiansWarehouse",
SourceID: '1234',
City: "Stockholm",
WarehouseName: "Sebastians Warehouse",
WarehouseType: "STORE"
}
)
.expectJSON('?.articles',{
articles: [],
DistrictID: [],
WarehouseID: "SebastiansWarehouse",
SourceID: '1234',
City: "Stockholm",
WarehouseName: "Sebastians Warehouse",
WarehouseType: "STORE"
}
)
.expectMaxResponseTime(500)
.toss();

you can include
.afterJSON(json){
//json.articles can be asserted here
//some more assertion on the response
}
which will parse the response and send it as an argument which can be asserted using simple javascript conditions, statements, loops etc.

Related

SuiteScript TypeError: Cannot read property "firstname" from undefined

I have a problem that's not making any sense to me. I have created a custom search and I am using the results from that search to addSelectOptions to a select field I have added.
However when trying to simply access a value within a nested object I am getting the error message: TypeError: Cannot read property "firstname" from undefined.
Here is the code:
var sfPlayersSearch = search
.create({
id: 'customsearch_pm_sf_players_search',
title: 'SF Players Search',
type: search.Type.EMPLOYEE,
columns: [
'entityid',
'firstname',
'lastname',
'custentity_pm_ws_sf_player',
],
filters: ['custentity_pm_ws_sf_player', 'is', 'true'],
})
.run()
.getRange(0, 100);
log.debug({ title: 'SF Players', details: sfPlayersSearch });
var player1ProxyField = form.addField({
id: 'custpage_pm_ws_sf_player_1_proxy',
label: 'Player 1 Proxy',
type: ui.FieldType.SELECT,
});
var player2ProxyField = form.addField({
id: 'custpage_pm_ws_sf_player_2_proxy',
label: 'Player 2 Proxy',
type: ui.FieldType.SELECT,
});
for (var i = 0; i < sfPlayersSearch.length; i++) {
log.debug({title: 'Result', details: sfPlayersSearch[i].values.firstname});
player1ProxyField.addSelectOption({ value: sfPlayersSearch[i], text: sfPlayersSearch[i].id });
}
JSON Object:
[
[
{
"recordType": "employee",
"id": "8",
"values": {
"entityid": "Artur X",
"firstname": "Artur",
"lastname": "X",
"custentity_pm_ws_sf_player": true
}
},
{
"recordType": "employee",
"id": "50",
"values": {
"entityid": "Darryl X",
"firstname": "Darryl",
"lastname": "X",
"custentity_pm_ws_sf_player": true
}
},
{
"recordType": "employee",
"id": "1983",
"values": {
"entityid": "Douglas X",
"firstname": "Douglas",
"lastname": "X",
"custentity_pm_ws_sf_player": true
}
},
{
"recordType": "employee",
"id": "86477",
"values": {
"entityid": "Paul X",
"firstname": "Paul",
"lastname": "X",
"custentity_pm_ws_sf_player": true
}
}
]
]
Any help greatly appreciated. I have tried doing .values || {}.firstname and this returns no error, but also no result.
Search.run().getRange() returns an array of Result objects. These are what you are iterating through in your for block. The Result object does not include values but rather includes methods for access the values getValue()) and text (getText()) of each result.
Change
log.debug({title: 'Result', details: sfPlayersSearch[i].values.firstname});.
to
log.debug({title: 'Result', details: sfPlayersSearch[i].getValue('firstname')});
While #krypton 's answer is correct for what you are doing you may find it useful to use Netsuite's JSONified version of search objects like what you see in your log.
If you were writing this as a library file where you might want to work in a Map/Reduce you can normalize the search result like
.getRange(0, 100)
.map(function(sr){
return JSON.parse(JSON.stringify(sr));
});
Now your original code for values.firstname would work.
Fun fact. If you are using SS 2.1 you can use let', const, and arrow functions:
const players = search.create()...
.getRange(0, 100)
.map(sr=>(JSON.parse(JSON.stringify(sr)));

Sequelize js reformat nested response

I am using PostgreSQL as database and Sequelize JS to Query my database. One of the APIs has below code
var video_attributes = [[sequelize.cast(sequelize.fn("like_count", Sequelize.col("video_id")), 'integer'), "total_likes"]];
if (request.user) {
video_attributes.push([sequelize.fn("has_liked", request.user.id, Sequelize.col("user_bookmark.video_id")), "is_liked"]);
video_attributes.push([sequelize.fn("has_bookmarked", request.user.id, Sequelize.col("user_bookmark.video_id")), "is_bookmarked"]);
}
mod_idx.user_bookmark.findAll({
where: {"user_id": request.user.id},
include : [{
model:mod_idx.video, as: "video",
attributes: {include: video_attributes}
}],
attributes: {exclude: ["user_id", "video_id", "id"]},
order: [[
"id",
"desc"
]],
}).then(video_list => {
let r = { "data": video_list, "success": true }
response.status(200).json(r)
}).catch(function (err) {
console.log(err)
});
It returns below response:
{
"data": [
{
"video": {
"id": 189,
"total_likes": 0,
"is_liked": false,
"is_bookmarked": true
}
},
{
"video": {
"id": 261,
"total_likes": 0,
"is_liked": false,
"is_bookmarked": true
}
}
],
"success": true
}
Expected result:
{
"data": [
{
"id": 189,
"total_likes": 0,
"is_liked": false,
"is_bookmarked": true
},
{
"id": 261,
"total_likes": 0,
"is_liked": false,
"is_bookmarked": true
}
],
"success": true
}
I tried by making "raw" as true but it returns column names as 'video.column_name' (https://stackoverflow.com/a/53612698/1030951).
I don't want to use map function as it may slowdown while processing large number of records.
It is not pretty but you can do this by adding all attributes at top level.
mod_idx.user_bookmark.findAll({
where: {"user_id": request.user.id},
include : [{
model:mod_idx.video, as: "video",
attributes: [] // Do not include anything in nested object
}],
attributes: [
[sequelize.cast(sequelize.fn("like_count", Sequelize.col("video.video_id")), 'integer'), "total_likes"]
// Add more here
],
order: [[
"id",
"desc"
]],
})
================================================================
Update
You can do something like this. One thing to consider here is that you must avoid the column name conflicts across multiple tables (as you are putting all attributes at top level), so add exclude or rename to make sure you handle the conflicts.
I demonstrate here for a scenario that I want to include all video attributes except certain columns to avoid conflicts.
const videoExcludeList = ['createdAt', 'updatedAt'];
// Get all video attributes minus exclude list.
const videoAttrs = Object.keys(mod_idx.video.rawAttributes)
.filter((v) => !videoExcludeList.includes(v))
.map((v) => Sequelize.col(`video.${v}`));
// Custom attributes that uses fn/rename/etc
const customAttrs = [
[sequelize.cast(sequelize.fn("like_count", Sequelize.col("video.video_id")), 'integer'), "total_likes"],
// Add more here.
]
You can also combine with top-level exclude to exclude columns from user_bookmark.
mod_idx.user_bookmark.findAll({
where: {"user_id": request.user.id},
include : [{
model:mod_idx.video, as: "video",
attributes: [] // Do not include anything in nested object
}],
attributes: {
exclude: ['id'], // exclude these columns from user_bookmark
include: [...videoAttrs, ...customAttrs],
},
order: [[
"id",
"desc"
]],
raw: true // You need this.
})

MongoDb find all objects that contain nested value

This is my user object sent as token in req:
{
"_id": "6212aba16653621e67393549c",
"name": "User",
"email": "user#gmail.com",
"__v": 0
}
This is my get function code:
const getSharedLists = asyncHandler(async (req, res) => {
const lists = await List.find({
sharedWith: { email: req.user.email },
});
res.status(200).json(lists);
});
This is what object looks like:
{
"_id": "621817233300dfff68e23710",
"user": "6212ab33383621e67393549c",
"listName": "test update",
"private": true,
"items": [
{
"itemName": "Bananas",
"quantity": 3,
"isBought": false,
"isle": "isle",
"_id": "621b043622147906eece2e72"
},
],
"sharedWith": [
{
"email": "user#gmail.com",
"_id": "621bdbf0791a322534284c49"
}
],
"createdAt": "2022-02-24T23:39:25.668Z",
"updatedAt": "2022-02-27T21:21:03.584Z",
"__v": 0,
},
I keep getting empty array back, even when hard code req.user.email as "user#gmail.com" for example. I need to find all lists on MongoDb that have my email in array of sharedWith.
Can somebody help please. Apparently I'm using List.find method wrong but can't seem to figure out the syntax.
You need (.) dot notation.
const lists = await List.find({
"sharedWith.email" : req.user.email
});
Sample Mongo Playground
Reference
Specify a Query Condition on a Field Embedded in an Array of Documents

Not able to query for nested relations using dgraph-orm

I am using dgraph-orm for fetching nested relational values but it works for single level but not multiple level.
I am getting the page details but unable to fetch the avatar of the page.
Here is my snippet:
let posts = await PagePost.has('page_id', {
filter: {
page_id: {
uid_in: [page_id]
}
},
include: {
page_id: {
as: 'page',
include: {
avatar: {
as: 'avatar'
}
}
},
owner_id: {
as: 'postedBy'
}
},
order: [], // accepts order like the above example
first: perPage, // accepts first
offset: offset, // accepts offset
});
I am not getting avatar for the attribute page_id:
{
"uid": "0x75b4",
"title": "",
"content": "haha",
"created_at": "2019-09-23T08:50:52.957Z",
"status": true,
"page": [
{
"uid": "0x75ac",
"name": "Saregamaapaaaa...",
"description": "This a is place where you can listen ti thrilling music.",
"created_at": "2019-09-23T06:46:50.756Z",
"status": true
}
],
"postedBy": [
{
"uid": "0x3",
"first_name": "Mohit",
"last_name": "Talwar",
"created_at": "2019-07-11T11:37:33.853Z",
"status": true
}
]
}
Is there a support for multilevel field querying in the orm??
There was some issue with ORM itself it was not able to recognize the correct model name for multilevel includes and generating the wrong queries.
Fixed the same in version 1.2.4, please run npm update dgraph-orm --save to update your DgraphORM.
Thanks for the issue.

Approaching JSON data returns 'undefined'

When I accessing "dept_name", the JSON returns 'undefined'.
How can I return correct output?
JSON object (content) from an API
"departments": [
{
"dept_no": "d005",
"dept_name": "Development",
"from_date": "1994-07-03",
"to_date": "9999-01-01",
"dept_manager": [
{
"emp_no": 110511,
"first_name": "DeForest",
"last_name": "Hagimont",
"email": "110511#cloud-spartan.com",
"from_date": "1985-01-01",
"to_date": "1992-04-25"
},
{
"emp_no": 110567,
"first_name": "Leon",
"last_name": "DasSarma",
"email": "110567#cloud-spartan.com",
"from_date": "1992-04-25",
"to_date": "9999-01-01"
}
]
}
],
when I accessing data['departments'].dept_no returns 'undefined'
var content_depart = content['departments'];
console.log(content_depart);
var department = content_depart.dept_name;
console.log(department);
console.log(content_depart)
[ { dept_no: 'd005',
dept_name: 'Development',
from_date: '1994-07-03',
to_date: '9999-01-01',
dept_manager: [ [Object], [Object] ] } ]
console.log(department)
undefined
data['departments'] is an array.
let data =
{ // v--------- array !
"departments": [
{ // ...
You can't access its members directly, but have to specify the index first. In example :
let data = {"departments":[{"dept_no":"d005","dept_name":"Development","from_date":"1994-07-03","to_date":"9999-01-01","dept_manager":[{"emp_no":110511,"first_name":"DeForest","last_name":"Hagimont","email":"110511#cloud-spartan.com","from_date":"1985-01-01","to_date":"1992-04-25"},{"emp_no":110567,"first_name":"Leon","last_name":"DasSarma","email":"110567#cloud-spartan.com","from_date":"1992-04-25","to_date":"9999-01-01"}]}]};
console.log(data.departments[0].dept_no);
Add index before accessing data
var department = content_depart[0].dept_name;
console.log(department);
content_depart is array not an object
so go with content_depart[0].dept_name

Resources