AH, a very simple question, but I can't seem to find the answer anywhere. This is my first set of postman tests. I have a request that returns this JSON response:
{
"requestId": "3dd0#170fa14fb64",
"result": [
{
"id": 52508,
"status": "deleted"
},
{
"id": 52507,
"status": "deleted"
}
],
"success": true
I want to write a test that verifies that both of the status objects within the result array will have the value "deleted" but I don't know the correct syntax to do so...so far I have this
pm.test("Test users deleted successfully", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.result[0].status).to.eql("deleted");
});
This works great for verifying the first status object, but how do I target the second one in that array?
You would need to loop through the result array:
pm.test("Test users deleted successfully", () => {
var jsonData = pm.response.json();
_.each(jsonData.result, (item) => {
pm.expect(item.status).to.eql("deleted");
});
});
I've used the Lodash .each() function here, which is built-in to Postman, but you can do this with a native JS for loop, it works the same way I just prefer this syntax.
More info:
https://www.w3schools.com/js/js_loop_for.asp
Related
I'm using React to create a web application. I have a DynamoDB table in AWS and an AppSync API configured.
I'm using the following to make an api call:
const [items, setItems] = useState([]);
useEffect(() => {
(async () => {
const apiGroups = await API.graphql(graphqlOperation(queries.getNtig, { PK: "Status", SK: "Active" }));
setItems(apiGroups.data.getNtig.Group);
})();
}, []);
Later on I use the results to create a dropdown. I had this working perfectly with Rest but I'm trying to switch to using GraphQL.
I see the JSON response in the webconsole:
{
"data": {
"getNTIG": {
"PK": "Status",
"SK": "Active",
"Group": [
"Group1",
"Group2"
]
}
}
}
I always get Unhandled Rejection (TypeError): apiGroups.data.getNtig is undefined
Any help greatly appreciated.
The problem is that the key you are referring to is named getNTIG and not getNtig. The language is case sensitive so it is important to use the right case.
I've been trying retrieve values from JSON and so far, been unsuccessful. It does get called on the front-end when I refresh the page, but the information is not passing to the next method. I think the issue might be down to the promises.push... line, as I've tried to debug the method underneath and the information is not being passed on at all.
AngularJS:
var promises = [];
promises.push(SpringDataRestService.get({"collection": "subjects"}).$promise);
// Require each of these queries to complete before continuing
$q.all(promises).then(function (data) {
// Grab the first result
$scope.available = data[0].subjects;
$scope.selected = [];
// If this is an update, get the second result in set
if (data.length > 1) {
// For each permission that is assigned to this role, add ID (name) to selected
for (var i = 0; i < data[1].data.subjects.length; i++) {
var perm = data[1].data.subjects[i];
$scope.selected.push(perm.name);
}
}
$scope.tableEditOptions = new NgTableParams({}, {
dataset: $scope.available
});
$scope.available, 'name');
}).catch(function (data) {
// ERROR
});
JSON:
[
{
"name": "FWGWG",
"description": "WGWGWG",
"lockId": 0
},
{
"name": "QFQFQF",
"description": "QFQFQFQ",
"lockId": 0
}
]
I'm confident as well my for loop is wrong due to assigning the values as well, since I don't think it should be data.subjects, but I understand these threads are only 1 issue per question. Any help would be greatly appreicated.
Use the query method for arrays:
var promise = SpringDataRestService.query({"collection": "subjects"}).$promise;
promise.then(function (dataArr) {
console.log(dataArr);
//...
}).catch(function (errorResponse) {
console.log(errorResponse);
});
With the REST services, the get method returns a JavaScript object and the query method returns a JavaScript array.
From the Docs:
$resource Returns
A resource "class" object with methods for the default set of resource actions optionally extended with custom actions. The default set contains these actions:
{
'get': {method: 'GET'},
'save': {method: 'POST'},
'query': {method: 'GET', isArray: true},
'remove': {method: 'DELETE'},
'delete': {method: 'DELETE'}
}
...
It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data.
For more information, see
AngularJS $resource Service API Reference
From a JSON stored in a variable I can get the name of the current id from a router function called show: function(id). However, when I fetch collection from an URL instead of using a JSON variable I get an undefined TypeError.
console.log(this.collection.get(id).get('name'));
What I have seen is that when I use a JSON variable the show function works fine, but when I fetch from URL, show function executes after fetch succeed.
What I am doing wrong? Why fetching from URL gets undefined? How can I make it work?
The following code is fictional, it only shows the relevant part of my code. See the two cases at the end of the code block.
jsFiddle here
// Data 1 with variable
var heroes = [
{"id": "1", "name": "Batman"},
{"id": "2", "name": "Superman"},
];
// Data 2 from url: http://example.com/heroes.json
[
{"id": "1", "name": "Batman"},
{"id": "2", "name": "Superman"},
];
HeroesCollection = Backbone.Collection.extend({
model: HeroesModel,
url: 'http://example.com/heroes.json'
});
HeroesRouter = Backbone.Router.extend({
// I use two shows to graphic this example
routes: {
'': 'index',
':id': 'show'
},
initialize: function(options) {
this.collection = options.collection;
this.collection.fetch();
// this.collection.fetch({async:false}); this fixes my problem, but I heard it is a bad practice
},
index: function() {
},
show: function(id) {
console.log(this.collection.get(id).get('name'));
// Case #1: When Collection loads from a Variable
// id 1 returns: 'Batman'
// Case #2: When Collection fetchs from URL, id 1 returns:
// TypeError: this.collection.get(...) is undefined
}
});
// Case #1: collection loads JSON from a variable
var heroesCollection = new HeroesCollection(heroes);
// Case #2: collection loads JSON with fetch in router's initialize
// var heroesCollection = new HeroesCollection();
var heroesRouter = new HeroesRouter({collection: heroesCollection});
How about this? It's been awhile, but this seems like a better approach to what you are trying to achieve. The basic concept is that once you navigate to your show route, it will execute show. This method will create a new, empty collection, and then fetch the data for it. Along with that, we pass in a success method (as François illustrated) which will execute when the request is finished with the JSON (which creates a collection of Heros).
I believe the reason you were running into the issue with the remote data is that you were trying to access this.collection before it was populated with data from the request.
You have to remember the request is asynchronous, which mean code execution continues while the request is processing.
HeroesCollection = Backbone.Collection.extend({
model: HeroesModel,
url: 'http://example.com/heroes.json'
});
HeroesRouter = Backbone.Router.extend({
routes: {
'': 'index',
':id': 'show'
},
index: function() {
},
show: function(id) {
this.herosCollection = new HerosCollection();
this.herosCollection.fetch({
success: function(collection, response, options) {
console.log(this.get(id).get('name'));
}
});
}
});
you need to trigger the router 'show' function when the collection has ended to load.
this.collection.fetch({async:false}); fixes your problem because the whole javascript code is waiting (async:false) the ajax call to be ended before going further.
The other and best solution is to wait that your collection is fetched before you try to use the results.
Basically:
MyCollection.fetch({
success: function(model, reponse) {
// do wtv you want with the result here or trigger router show method...
}
});
Using the included http post, I should get back the JSON object below. I want to take the LeagueDictionary data in the JSON below and create an object so I can use it in a for each loop on my client, but I can't wrap my head around how to structure that code in the http call.
{
"Id": 0,
"UserName": null,
"NickName": null,
"Email": "email#company.com",
"Password": null,
"Admin": false,
"Validated": false,
"Key": "oOE0QbOhjK17pNeKDPEFti5On27R3b",
"LeagueDictionary": {
"1": "League #1",
"2": "League #2"
}
}
using this call:
$scope.getLeagues = function() {
$http({
method: 'POST',
url: 'http://xxxxxxxxxxxxxxxxxx',
data: ???,
})
}
If someone give me a nudge on how to data bind that particular part of the JSON, I'd appreciate the help. I'm not sure how to strip the LeagueDictionary section out and make an object out of it.
You could set up a service that gets your data, so you can get $http and such out of your controller. Say...
app.factory('DataService', function ($http) {
return {
get: function () {
return $http.get('data.json'); // post & url goes here
}
};
});
In your controller, use then to access the response data after promise has been resolved (catch() and finally() are available, too).
app.controller('MainCtrl', function ($scope, DataService) {
DataService.get().then(function (response) {
$scope.leagueDictionary = response.data.LeagueDictionary;
});
});
Related HTML template would be
<body ng-controller="MainCtrl">
<div ng-show="leagueDictionary">
<span ng-repeat="(key,val) in leagueDictionary">
{{ val }} <br>
</span>
</div>
</body>
Using your data this gives you
See example plunker here http://plnkr.co/edit/j6bmmQ
You can just access the LeagueDictionary property of the response, and then iterate over that in ng-repeat. Obviously I don't know exactly what your scopes look like, but this should get you started:
//JS
$http.post('/someUrl', { 'foo': 'bar' }).success(function(data) {
myController.myModel.leagueDictionary = data.LeagueDictionary;
});
//HTML
<tr ng-repeat="(leagueNum, leagueName) in leagueDictionary">
I'm introducing in Angular with its Tutorial "Phonecat".
Against the tutorial I'd like to build a simple app with a list and detail view with only one json, containing all informations.
The list-view (showing complete content of the json) works fine but I'm struggle with how to set my Angular services for the detail-view.
I am using the XHR method:
Controller.js:
function PlaygroundDetailCtrl($scope, Playground) {
$scope.playgrounds = Playground.query();
}
Services.js
angular.module('playgroundcatServices', ['ngResource']).
factory('Playground', function($resource){
return $resource('playgrounds/playgrounds.json', {}, {
query: {method:'GET', isArray:true}
});
});
playground.json
[
{
"id:" 1,
"properties": "true"
"lat": "51.347789"
"lon": "12.232234"
},
{
"id:" 2,
"properties": "false"
"lat": "51.347789"
"lon": "12.766667"
}
]
I want Angular to display only one entry (id:1) with its properties.
What is the smartest way to do that: showing again all and then filter?
I am stumped.
Use an Angular filter on your view (there's no need to filter the data on the service):
<div ng-repeat="entry in playgrounds | filter:{id: 1}">
<p>properties: {{entry.properties}}</p>
<p>lat: {{entry.lat}}</p>
<p>lon: {{entry.lon}}</p>
</div>
jsfiddle: http://jsfiddle.net/bmleite/Ad6u9/
This worked out quite good:
Controller:
function PlaygroundDetailCtrl($scope, $routeParams, $http) {
$http.get('playgrounds/playgrounds.json').success(function(data){
angular.forEach(data, function(item) {
if (item.id == $routeParams.playgroundId)
$scope.playground = item;
});
});
I've got exactly the same scenario now I think (I'm guessing you're developing with 'mobile' in mind (as I am and want to minimise data transfer) - I'm using one 'master json file', and then on my detail view just filtering that json file (so that the json doesn't have to be reloaded) on the ID value.
This is totally untested but your code from the original question should be modified something like this:
angular.module('playgroundcatServices', ['ngResource'])
.factory('Playground', function($resource){
return $resource('playgrounds/playgrounds.json', {}, {
query: {method:'GET', isArray:true}
});
});
function PlaygroundDetailCtrl($scope, Playground) {
Playground.query(
// params (none in this case)
{},
// Success
function (data) {
$scope.playgrounds = data.filter(function (o) {
return o.id == $routeParams.playgroundId; // assuming you've set this up in your routes definition
})[0];
},
// Error
function (data) {
//error handling goes here
}
);
}
You may want to put something like $scope.isDataLoaded = true; in your 'success' handler as well, and do a watch on that, to use to check to see when the data has finished loading (eg. for in a directive).
I'm not super happy with the [0] in there, but it think the solution is better than a forEach loop myself.