I am trying to do an update operation using Mean Stack with Angular 4. I am new to this technology. For update oprtn I need to map the values to UI form based on id selected to update the record. My data service is fetching record values from MongoDb database in the form of JSON which needs to be updated. However, I am unable to set those parameters to the fields present over the form in the typescript code.
I am using JSON.parse method for implementing it But getting below error.
Error: SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse ()
Typescript code
updateitem(itemid){
let updatedresult;
console.log("toupdateid", itemid);
this.dataService.getItemById(itemid)
.subscribe(
res=> {
this.res =JSON.parse(res);
this.newSession.trainingName =res["TrainingName"],
this.newSession.description = res["Description"];
console.log('newsession', this.newSession);
},
err=> this.apiError = err,
() => {
this.getFormdetails();
}
)
}
dataservice
getItemById(id):Observable<any>{
console.log('idvalue', id);
return this.http.get("http://localhost:3000/getitem"+"/"+ id)
.map(result =>{ this.result = result.json();
console.log('getitembyid' ,result.json())})
.catch((error:any) => Observable.throw('Server Error to get the item'));
}
}
.map(result =>{ this.result = result.json();
console.log('getitembyid' ,result.json())})
Change it to
.map(result => result.json())
And remove the JSON.parse in ts code as now it will return from the service as a JSON object itself
That error occurs when server sends a invalid json. You need to check response of the server.
there are different reasons for that but most likely:
you are sending your request to a wrong endpoint. So instead of json you get a document starting with u and it tries to parse it.
Another one is server sending you a wrong response which is not in JSON format. Try to see if response is turned into a json string on server side.
But since it starts with u its most likely trying to parse an undefined string. I sugest instead of subscribing function you should nest promises like following.
getItemById(id):Observable<any>{
console.log('idvalue', id);
return this.http.get("http://localhost:3000/getitem"+"/"+ id).then(result => {
return result.json();
}) //this will return promise
.catch((error:any) => Observable.throw('Server Error to get the item'));
}
}
and on your updateItem
updateitem(itemid){
let updatedresult;
console.log("toupdateid", itemid);
this.dataService.getItemById(itemid)
.then(
res=> {
this.res =JSON.parse(res);
this.newSession.trainingName =res["TrainingName"],
this.newSession.description = res["Description"];
console.log('newsession', this.newSession);
this.getFormdetails();
}).catch(err => {
this.apiError = err
})
)
}
Related
I am trying to check states after sending requests to the server by using axios. I designed the server that if you submitted the form with an empty input, you will get an error. If you can see in the code, I have tried to check the states in finally block but it is not working properly. Like when I submitted the form initially with no inputs, the console log displays no errors and when I try to submit the form with the inputs, it doesn't display anything in the console. I just want to check if there is an error with the request because I want to run a function between them.
The server I used is live and running and you can get the data/submitted form by changing the URL into /getUser
Code here: https://codesandbox.io/s/quizzical-danny-dv1l7?file=/src/App.js
It doesnt works like that.
const [error, setError] = useState("");
error is the initial value (empty string). In dont realy knows how useState is working but, error is a string so it s a value, not a reference. There is no way this variable get updated it the finaly block.
The simple answer is you are setting your state inside the function and then trying to read it as your "current state". Try this instead...
const handleSubmit = async (e) => {
e.preventDefault();
try {
await axios.post("https://testing-name-app.herokuapp.com/create", {
first,
last
});
} catch (error) {
console.log("error found");
return setError(error.response.data.errorMessage);
}
// be CAREFUL with this pattern! This just means the request came back
// with no errors, but there may be a message from your call that
// contained an error from your db/server etc
return console.log("no errors");
};
And here's a way to quickly see what's going on in your call...
const handleSubmit = async (e) => {
e.preventDefault();
let res
try {
res = await axios.post("https://testing-name-app.herokuapp.com/create", {
first,
last
});
} catch (error) {
res = error
console.log("error found");
setError(error.response.data.errorMessage);
}
finally {console.log('res: ', res)}
};
I want to get the result from the closure function. I did try doing some callback functions too but still I'm getting the same issue. I was able to console.log the result inside the closure/callback but can't return the response into a variable. I tried some of the solutions posted already but weren't able to succeed.
Here's my code:
var fcmTokens = [input.fcmToken];
switch(topicType) {
case 'post':
const username = (input.username).toLowerCase();
const userPrefix = Config.get(`setting.topic.user.prefix`);
fcmTokens = Topic.get(`${userPrefix}-${username}`, {AttributesToGet : ['fcmToken']}, function(err,foundTopic) {
var result = foundTopic.attrs.fcmToken;
console.log(result) //Able to log my expected result
return result;
})
console.log(fcmTokens) //undefined
break;
}
I was able to resolve my own issue by installing a library called promisified-vogels as my Model is using a DynamoDB.
From my current code above to this:
let userTopic = await Topic
.getAsync(`${userPrefix}-${username}`,{ConsistentRead: true, AttributesToGet : ['fcmToken']}) //from original function "get" changed to "getAsync"
.then(function(user){
return user.attrs.fcmToken;
})
.catch(function(err){
console.log(err)
});
fcmTokens = userTopic; // i was able to get the list of record im expecting.
Reference Library : https://github.com/servel333/vogels-promisified
Hello I am still a beginner in Nodejs and MongoDB. When I am running res.render() function as shown below I get 2 console logs, first with the correct result from mongodb find query and second with null. If I remove res.render() It works properly with only one console.log() output and not the second null.
router.get('/:areaslug', (req, res) => {
// Query results
let areavar = {}
return client.db("AwesomeApartments")
.collection("areas")
.findOne({slug: req.params.areaslug
})
.then((datadb) => {
// first time shows correct results next it shows null
console.log(" bug-testing : "+JSON.stringify(datadb));
//storing result of first query to my object
areavar = datadb;
return client.db("AwesomeApartments")
.collection("apartments")
.find({area:datadb._id})
.toArray()
})
.then((apartmentdb) => {
// Storing results of second query
areavar.apartments = apartmentdb;
//removing this solves the issue
return res.render('area',areavar);
}).catch(err =>
{
console.log(err);
return;
})
});
To those who find their way here, browser was generating two get requests. First one for query and second one for favicon.ico. Handling favicon.ico request solved this issue.
After making a subscription from Angular service, the returning results are bunch of duplicates. For every call, the number of duplicates increase by one.
I tried console logging the results at various stages of the app. The duplicates are returned immediately after the promise get rendered
Angular Service code:
GetUserPendingApprovals(userid: string) {
let approvalsPending: any[] = [];
this.http
.get<{message, approvals: any}>(`/api/approvals/${userid}`)
.subscribe(approvals => {
console.log(approvals.approvals);
approvalsPending = approvals.approvals;
this.approvalsUpdated.next(approvalsPending);
approvalsPending = [];
});
}
getUserPendingApprovalsUpdateListener() {
return this.approvalsUpdated.asObservable();
}
node end point:
app.get("/api/approvals/:userid", (req, res, next) => {
// const urlData = req.params.userId;
//console.log(urlData);
const query = datastore
.createQuery('approvals')
.filter('src', '=', req.params.userid);
query.run().then(approvals => {
approvals.forEach(approval => console.log(approval));
console.log(approvals[0].length);
res.status(200).json(
{
message: "Request was processed successfully!",
approvals: approvals[0]
}
);
})
})
The console logging on node endpoint returns a proper count value for the results being queries for. However, console logging of the same results on the Angular service code returns duplicates and the number of duplicates increase by one for every call. Example: 1st call - 2 duplicates, 2nd call - 3 duplicates, 3rd call - 3 duplicates and so on.
More information...
I am making nested subscription from my angular component. Something like below -
ngOnInit() {
this.activatedRoute.params
.subscribe(
(params: Params) => {
....some code goes here...
this.revenueService.GetUserInvoicesThisWeek(this.userid);
this.currentWeekInvoicesSub = this.revenueService.GetUserInvoicesThisWeekListener()
.subscribe((revenueInfo: Revenue[]) => {
....some code goes here...
});
this.currentDayInvoicesSub = this.revenueService.GetUserInvoicesTodayListener()
.subscribe((todayRevenueInfo: Revenue[]) => {
....some code goes here...
});
this.approvalsService.GetUserPendingApprovals(this.userid);
this.approvalsSub = this.approvalsService.getUserApprovalsUpdateListener()
.subscribe((approvalsPending: any[]) => {
....some code goes here...
});
});
}
The last subscription is where i am facing problems. But i am pretty sure the rendered promise right after the node endpoint call is returning duplicates. Something which i mentioned in the beginning of this question.
Doubts:
What would be the root cause for these duplicates?
How to resolve this issue?
You are subscribing everytime this function gets called, so you're making a duplicate subscription everytime you change your route.
GetUserPendingApprovals(userid: string) {
let approvalsPending: any[] = [];
this.http
.get<{message, approvals: any}>(`/api/approvals/${userid}`)
.subscribe(approvals => {
console.log(approvals.approvals);
approvalsPending = approvals.approvals;
this.approvalsUpdated.next(approvalsPending);
approvalsPending = [];
});
}
Subscribe in the component instead in the service to fix this issue.
GetUserPendingApprovals(userid: string) {
return this.http
.get<{message, approvals: any}>(`/api/approvals/${userid}`)
}
Component ts:
ngOnInit(){
this.aprovalSub = this.approvalsService.GetUserPendingApprovals(this.userid);
.subscribe(approvals => {
approvalsService.approvalsPending = approvals.approvals;
approvalsService.approvalsUpdated.next(approvalsPending);
});
}
ngOnDestroy(){
if(this.aprovalSub !== undefined) this.aprovalSub.unsubscribe()
}
Clean up subscriptions when component gets destroyed or they will stay in memory and you will have subscriptions taking up memory.
So starting first my nodejs server sends this as a response
"["name1","name2","name3"]"
but my angular 2 code for service is
return this.http.get(this.config.apiUrl + '/folder').map((response:Response)=> {
response.json();
console.log(response); }
How do I fetch the array?
If I use response._body there will be an error in npm start stating "._body undefined", so I make it as a comment then after npm start I reverse back, I know it is not proper way. Here is the console.log of above service code
Response
headers: Headers
ok:true
status:200
statusText:"OK"
type:2
url:"http://localhost:4000/folder"
_body:"["name1","name2","name3"]"
__proto__:Body
The main problem is to fetch in component in an array
Here, is the code I am trying
this.photoService.getAllfolder().subscribe(
data => {
console.log(data);
},
error => {
console.log(error);
});
You are missing a return statement in your mapping. Also if you then want to have the console log, you need to change the order. Your code should therefore look like this:
return this.http.get(this.config.apiUrl + '/folder')
.map((response:Response)=> {
console.log(response);
return response.json(); // return
}
you can get data in lot of ways easy way was response["_body"] or response.text()
return this.http.get(this.config.apiUrl + '/folder').map((response)=> {
response["_body"];
console.log(response); }