JSON Property Undefined even thought the variable containing the Data is populated with a JSON object - javascript

I am trying to receive a MongoDB document from my database through a get request. I have tested the URL via Postman and is returning the document as expected. This has made me aware that the issue is in the frontend and not the Server.
When I do the same via my frontend, it retrieves the data, and is stored in the variable res and assigned to this.englishteam so it can be accessed outside the function scope of GetSingleEnglishTeam.
public teamenglish!:EnglishTeam;
GetSingleEnglishTeam(_id: string) {
this.englishTeamService.GetSingleEnglishTeam(_id).subscribe((res)=>{
console.log("The team: "+ res);
this.teamenglish = res;
// console.log(this.teamenglish);
})
}
However, when I try to access the ClubName stored in teamenglish I get an undefined error
ERROR TypeError: Cannot read property 'ClubName' of undefined
at ClubHonoursComponent_Template (club-honours.component.html:9)
Club-honours.component.html
<div class="row">
<div class="column">
<div class="PremierLeagues" >
{{teamenglish.ClubName}}
</div>
</div>
Get Request to the Server
GetSingleEnglishTeam(_id: string){
console.log( "ID is "+_id);
return this.http.get<EnglishTeam>('http://localhost:3000/api/getTeamEn/' + `${_id}`);
}
When I console log the variable containing the JSON object I get [Object Object].
What I want to do is be able to send a getOne request to the server and the server to return the single document. Can anyone see where I have gone wrong?

The problem is that the template is initialised before teamenglish variable could be set in callback of subscribe.
You can solve this by 3 methods -
1.) In your template file use Safe navigation operator (?) i.e. -
{{teamenglish?.ClubName}}
2.) Use *ngIf on container div to only render itself if teamenglish is available to use (which will be available to use once your observable callback sets it to teamenglish i.e. -
<div *ngIf="teamenglish" class="PremierLeagues" >
{{teamenglish.ClubName}}
</div>
3.) Use async pipe in your template to automatically handle the subscription and value resolution i.e.
In your ts file, assign the observale to a variable like -
const obs = this.englishTeamService.GetSingleEnglishTeam(_id)
Then in your template file -
{{obs | async | json}}

Related

MongoDB _id returns undefined on frontend (VueJS)

I created a simple fullstack webapp using NodeJS & Express + MongoDB to build the backend API and Vue.JS for the frontend.
All the Write Read and Delete API worked perfectly (I tested it using Postman). Everything works perfectly as well on the frontend, except when I tried to iterate (v-for) on an array of objects to get the _id, it doesn't work.
The array called posts has the attributes of 'text' and 'createdAt'. The v-for works perfectly and output the 2 attributes as expected. However, I tried to output _id (default id from MongoDB) but it returned "undefined".
This causes a problem because if I can't get _id, it wouldn't be possible for me to delete a specific post using the existing backend delete API.
From my understanding, in the backend side, the _id needs to be converted into ObjectId first before it can be used for db querying. But on the frontend (vue) I am not sure on how can turn _id into ObjectId. Am I getting into the right direction here?
<div class="post" v-for="(post,i) in posts " :key="post._id" :index="i" :item="post" #dblclick="deletePost(post._id)">
{{post.createdAt.getDate()}}/{{post.createdAt.getMonth() + 1}}/{{post.createdAt.getFullYear()}}
<p class="text">{{post.text}}</p>
</div>
...
methods: {
async deletePost(id){
console.log(id) //this returns undefined
await PostService.deletePost(id);
this.posts = await PostService.getPosts();
}
},
...
//del post in PostService.js
static deletePost(id){
return axios.delete(url+id)
}
//backend delete api
router.delete('/:id',async (req,res)=>{
const posts = await loadPostCollection()
console.log(ObjectID(req.params.id))
await posts.deleteOne({_id: ObjectID(req.params.id)});
res.status(200).send()
})
expected output: _id of each 'post', e.g:5cfa8c29f74c65ae485a6d93
actual output: undefined
no error message(s).
You need to add the property reference post, like this:
<div class="post" v-for="(post,i) in posts " :key="post._id" :post="post" #dblclick="deletePost(post._id)">
{{post.createdAt.getDate()}}/{{post.createdAt.getMonth() + 1}}/{{post.createdAt.getFullYear()}}
<p class="text">{{post.text}}</p>
</div>
You don't have to convert _id to Mongo ObjectID on the FrontEND.
Your code looks normal, send all post object to function like that and debug it.
#dblclick="deletePost(post)"
Probably your backend return _id as an object.

passing non-url encoded parameters to an ajax call in node.js

I am trying to pass parameters from my website to a couchdb server through a node.js server.
I absolutely need to pass {} in a url. Not a string, not an empty object, the actual {} characters. It is used to define the end_key parameter in couchdb views.
At the moment, my call goes like this :
let url = "/trades";
let ajax_options = {
data:{
design_name:'bla',
view_name:'blabla',
params_view:{
group_level:2,
start_key:["1",0],
end_key:["1",{}]
}
}
};
$.ajax(url,ajax_options).then((res) => { ... });
when it passes through NodeJs and the nano library with
db.view(req.query.design_name, req.query.view_name, req.query.params_view)
the end_key object in params_view becomes ["1"] instead of ["1",{}] which I would like to see.
I have verified that with the correct value for end_key, the view gives me the expected result.
How to prevent that behavior from occurring ?

API Connect - 500 error when including basic Javascript

I'm trying some basic API Connect tutorials on IBM's platform (running locally using loopback) and have got completely stuck at an early point.
I've built a basic API service with some in-memory data and setter / getter functions. I've then built a separate API which takes two GET parameters and uses one of my getter functions to perform a search based on two criteria. When I run it, I successfully get a response with the following JSON object:
[{"itemId":1,"charge":9,"itemSize":2,"id":2}]
I've then tried to add a piece of server logic that modifies the response data - at this point, I'm just trying to add an extra field. I've added a Javascript component in the Assemble view and included the following code (taken from a tutorial), which I thought should modify the message body returned by the API while still passing it through:
//APIC: get the payload
var json = apim.getvariable('message.body');
//console.error("json %s", JSON.stringify(json));
//same: code to inject new attribute
json.platform = 'Powered by IBM API Connect';
//APIC: set the payload
//message.body = json;
apim.setvariable('message.body', json);
Instead of getting an extra JSON parameter ("platform"), all I get is a 500 error when I call the service. I'm guessing that I'm doing something fundamentally wrong, but all the docs suggest these are the right variable names to use.
You can't access json.platform but at that point json variable is json type. Are you sure that you can add a property to a json type variable if your json object lacks of that property? I mean: What if you first parse the json variable of json type to a normal object, then add new property, and finally stringify to json type again for body assigning purposes?
var json = JSON.parse(apim.getvariable('message.body')); //convert to normal object
json.platform = 'Powered by IBM API Connect'; //add new property
apim.setvariable('message.body', JSON.stringify(json)); //convert to json again before setting as body value
You need to get the context in some determined format, and in this function do your logic. For example if your message is in json you need to do:
apim.readInputAsJSON(function (error, json) {
if (error)
{
// handle error
apim.error('MyError', 500, 'Internal Error', 'Some error message');
}
else
{
//APIC: get the payload
var json = apim.getvariable('message.body');
//console.error("json %s", JSON.stringify(json));
if(json){
//same: code to inject new attribute
json.platform = 'Powered by IBM API Connect';
//APIC: set the payload
//message.body = json;
apim.setvariable('message.body', json);
}
}
});
Reference:
IBM Reference
You have the message.body empty, put a invoke/proxy policy before your gateway/javascript policy for example.

Display data from web service (Js, Angular)

I've been trying to display some data from a web service with no luck
I tried this
ngOnInit(){
//console.log(this._productoService.getDeudas());
this._productoService.getDeudas().subscribe(
result =>{
console.log(result.Cuotas);
}
);
}
}
and i got this error
Property 'Cuotas' does not exist on type 'Response'.
this is the data i got in the console
any ideas? thanks in advance
Response is an object and therefore you can use...
result => { result ['Cuotas']; }
... the [result ['Cuotas']] field access stands out because you use bracket notation to access the results field. If you tried to write [result.Cuotas], TypeScript would correctly complain that the Object coming back from HTTP does not have a results property. That's because while HttpClient parsed the JSON response into an Object, it doesn't know what shape that object is.
https://angular.io/guide/http

Extract from a NODE-RED string

I have my NODE-RED schemma:
following string result from my "Function" node my node:
msg.payload : string[63]
"{"random":{"date":"22:55","random":21},"time":{"time":"22:52"}}"
This is the code of my "Function Node":
msg.payload.random=context.global.randomandtime;
msg.payload.time=context.global.time;
return msg;
I need to put in "part of the string" (not all) like this =>{"date":"22:55","random":21} and show it in my browser like a webpage but not using html tags.
Like this:
22:55
21
Any help will be wellcome.
I have added template(Mustache) and I am traying to bring data to it,(Note:http response is already in schemme but not shown here)
I am traying to bring data here (template). But I get error.
The Mustache template body is:
This is the payload: {{#payload.randomandandtime.random}} !
But I have back this error back:
2017-5-18 16:18:00node: Mustachemsg : string[56]
"Unclosed section "payload.randomandandtime.random" at 59"
In browser I get
502 Bad Gateway: Registered endpoint failed to handle the request.
Even If I change it only payload.randomandandtime I get empty:
payload.randomandandtime
In browser & console:
Messsage received back: (empty)
This is the payload: !
Finally I solved in this way.
I make all in one Global varaible instead 2 global variables.
I passed it to mustache template and in Mustache I worked with context in order to get it.
General Scheme:
Then in recoverydata:
msg.payload = context.global.get("randomtime");
In My Mustache:
`{{#payload.random}}
Last random number request returned {{&payload.random}}, which was received
at {{&payload.randomtime.times}}{{/payload.random}}
{{/payload}}`
The resul of it is a Webservice not using HTML and this is:
url https://....../page
"Time last server time request received at 13:14 Last random number request returned 94, which was received at 13:14"

Categories

Resources