How do I make a GET call to a REST API with the below signature:
http://www.example.com/hierarchies/nodes/1005/parents
I am trying to call the API like so:
var service = Restangular.all('hierarchies');
return service.one('nodes', id).all('parents').get();
But it throws the following error:
TypeError: Cannot read property 'toString' of undefined
The API call(if successful) would respond in a nested format as below:
{
name: "",
children: [
{
name: "",
children: [
{
name: "",
children: [
..
]
}
]
}
]
}
Thanks in advance!
I think if you use all as the last part of the builder, a list is expected and you should use getList instead of get. However the object you are expecting does not look like a list, so you could change the last part of your builder to just use one without the second parameter and then a single object as the response will be expected.
service.one('nodes', 5).one('parents').get().then(function(response) {
});
Related
I am trying to access a nested object in ReactJS. This is what the object looks like:
const characteristics = [
{ id: "geo", content: 'Geopolitical' },
{ id: "dog", content: 'Dog Loving' },
];
const starterColumns = {
"1": {
name: 'I am',
items: characteristics
},
"2": {
name: 'fullstack developer',
items: []
}
}
const [columns, setColumns] = useState(starterColumns);
This is the error I get when I try to console.log(columns['2']['items']['0']['id']):
TypeError: Cannot read property 'id' of undefined
Does this have to do with the fact that I am working with a stateful variable? Is something funky going on with the nested objects? Thanks for the help!
EDIT
The problem was that there was no object in the column so I had no object to access. Now the problem outstanding is how do I fill that void without displaying a new drag and drop piece. Thanks for helping!
EDIT
I used a try/catch statement to check the object so if it is empty, nothing happens.
Use try catch only for errors that you can't handle
To access an element use dot notation whenever it's possible instead of using bracket notation []
When there is an empty array in the items you can't access to the id you will get an error so the solution is to check if the array is not empty
columns['2'].items.length > 0
To access the first element of an array you have to use [0] instead of ['0']
try this solution
if (columns['2'].items.length > 0) {
console.log(columns['2'].items[0].id)
}
I am trying to retrieve data from the backend. These are the relevant parts of my code:
API call
getData(PrimaryId:number):Observable<DataDto[]>{
return this.httpClient.get(`${this.prefix}/<xyz>/${PrimaryId}/xyz`) as Observable<DataDto[]>
}
Component TypeScript
onRetrieveClicked() {
this.xyzService.getData(this.PrimaryId).subscribe(
(xyz: DataDto[]) => {
this.xyz = xyz
console.log(this.xyz)
console.log(this.xyz.forEach((data)=>data.name)
})
}
First console.log output
{content: Array(1), pageable: {…}, totalPages: 1, totalElements: 1, last: true, …}
content: Array(1)
0: {name: max, name: null, asset: null, …}
length: 1
..........
But when I try to print only the name in the second console, it says that forEach is not a function. How can I solve this
edit
Dto model
export interface DataDto {
name: string
asset: abcDto
status: StatusDto
tasks: efgDto[]
nextDate: string
}
The xyz variable that you type as DataDto[], an array, is actually an object. This can be seen in your console.log, an array would be enclosed in [], not {}
is an object --> {
content: Array(1), pageable: {…}, totalPages: 1, totalElements: 1, last: true, …}
content: Array(1)
0: {name: max, name: null, asset: null, …}
length: 1
}
The data you are looking for is most likely the response object's content so add an import for import {map} from 'rxjs/operators'; and transform the data you've gotten from the response:
this.xyzService.getData(this.PrimaryId).pipe(
map((xyzResponse: any) => xyzResponse.content)
).subscribe(
(xyz: DataDto[]) => {
this.xyz = xyz;
console.log(this.xyz);
let dataNames = xyz.map(data => data.name);
console.log(dataNames);
}
I've typed xyzResponse as any but you could ofcourse create a reusable type for it if the API always returns the object with content, pageable, totalPages, ...
Rxjs is the library that Angular uses to handle asynchronous programming, such as HTTP calls or component events. Rxjs chains asynchronous manipulations together in a pipe (hence the .pipe call). Inside of this pipe rxjs expects a chain of operators that will perform operations on the asynchronous data, one by one. The map operator takes the input value and returns a new value so that the value you subscribe to has been transformed from the HTTP response to the .content field of the HTTP response.
Working in this way fixes all TypeScript compiler errors and allows you to chain additional calls later, like retrying if the API times out, or catching errors, or merging in other HTTP calls.
It seems that your this.xyz is not an array, but has an array property called content, you should modify your response object in order to accept it.
You can check if your objects are arrays with the following method
Array.isArray(obj)
Update your code to this.
this.xyzService.getData(this.PrimaryId).subscribe(
(xyz: NewObject) => {
this.xyz = xyz
console.log(this.xyz)
//If you have doubts of what is comming is nice to check if your property is an array
if(Array.isArray(this.xhy.content) {
console.log(this.xyz.content.forEach((data)=>data.name) });
}
}
Create a new object in order to support your response
class NewObject {
content: Array<DataDto>
// other values here
}
Another approach is like #Robin says in the comment
this.xyzService.getData(this.PrimaryId).subscribe((xyz: {content: DataDto[]}) =>
{
this.xyz = xyz
console.log(this.xyz)
//If you have doubts of what is comming is nice to check if your property is an array
if(Array.isArray(this.xhy.content) {
console.log(this.xyz.content.forEach((data)=>data.name) });
}
}
It's because you are trying to loop through an object instead of array
I think you can try this:
console.log(this.xyz.content.forEach((data)=>data.name) })
New here so my description might be bad but I'm trying to access the values on the second level of my JSON but I can't seem to get it. It only brings the values of the top level.
My JSON body looks like the following:
{
"services": [
{
"nameLevel1": "Example1",
"secondServices": [
{
"id": 1,
"namelevel2": "Example2",
}
]
}
]
}
And when I call it, I only can get the nameLevel1 and that is it. My GET method is this:
$scope.retrieveServices = function (id) {
SpringDataRestService.get(
{
"collection": "user",
"resource": id
},
function (response) { // Success Function
$scope.userServices = response.services;
$scope.recievedValues = true;
}
);
};
Now I originally thought all I would have to do is:
$scope.userServices = response.services.secondServices;
But I'm getting an undefined issue. So my query is how do I access all of them? My JSON body when doing a log output does show everything, but for some reason I can't seem to get it to show everything in my table. Only the nameLevel1 values.
Any help would be appreciate, and I hope my description is okay. Edits would be get as well since not too sure if I have labelled this correctly. Thank you!
I am using Angularjs $q.all(promises) to make multiple REST call and then collecting the data once promise is successful. I have following following.
If "promises is simple array then it works Plunker
var promises = [
Users.query().$promise,
Repositories.query().$promise
];
If "promises" is simple object then also it works Plunker
var promises = {
users: Users.query().$promise,
repos: Repositories.query().$promise
};
If "promises" is nested object then it is not working. For my requirement I need nested object to remember the input parameters. Plunker
var promises = {
users: {"phx":Users.query().$promise},
repos: {"phx":Repositories.query().$promise}
};
These plunkr are just to simulate my problem. However I want this approach in real project for following requirement.
I have list of 12 product
Each product has "details", "benefits" and "offers" data
I have separate REST API services for "details", "benefits" and "offers" having :productID as parameter
I am making call in following order
a. Loop for each cards
b. For each card, make a REST API call for "details", "benefits" and "offers"
c. Add #b steps into "promises" object
d. call
$q.all(promises).then(function(results) {
// Here need logic to compile the result back to product
// and corresponding "details", "benefits" and "offers" mapping
}
and get the data back
Following is json structure I needed to collect my response.
{
"prod1": {
"benefits": {},
"offers": {},
"pages": {
"productPage": {}
}
}
},
"common": {
"benefits": {},
"pages": {
"commonBenefit": {}
},
"others": {}
}
How can I achieve this?
If you really need it, you can wrap the nest with $q.all like this:
var promises = {
users: $q.all({"phx": Users.query().$promise}),
repos: $q.all({"phx": Repositories.query().$promise})
};
plnkr.co
When i try to compute this line
var project = Ext.create(CarboZero.model.Project,{strTitle: title ,strType: type ,strVersion: "1.0.0" ,dateEventDate: new Date() , arrCategory: "Energy"});
with this model definition
Ext.define('CarboZero.model.Project', {
extend: 'Ext.data.Model',
singleton: true,
config: {
fields: [
{
name: 'arrCategory'
},
{
name: 'strTitle'
},
{
name: 'dateEventDate'
},
{
name: 'strVersion'
},
{
name: 'strType'
}
]
}
});
It does not work and give me the error
Uncaught TypeError: Object [object Object] has no method 'substring'
Not quite sure what i do wrong, but im pretty sure its in the parameters has i normally write it that way and it works fine (without parameters).
You will get this kind of error if you had chose to make your model a Singleton.
Because Singleton are initialized at app startup and that you don't ever need to do it your self.