Dynamically adding post at the site using Observables (Angular) - javascript

I need to display posts dynamically on my home page. I have textarea above the post lists and my goal is to display new post immediatelly after it would be added, on the top of the post list. Component with textarea form is called add-post-component and it use onSubmit event:
onAddPostSubmit() {
if (this.authService.loggedIn()) {
const post = {
content: this.content,
creator_username: JSON.parse(localStorage.getItem('user')).username,
rate: 0
};
this.postsService.addPost(post).subscribe(data => {
if (data.success) {
console.log('Post added');
this.router.navigate(['/']);
} else {
console.log('Post not added' + JSON.stringify(data));
this.router.navigate(['/']);
}
});
} else {
console.log('Not logged');
return false;
}
}
Component of my main page is called Feed-component
this.postsService.getPosts().subscribe(response => {
this.posts = response.posts.reverse();
}),
err => {
console.log(err);
return false;
};
this.subscription = this.postsService.fetchPost().subscribe(post => {
this.postsService.getPosts().subscribe(response => {
this.posts = response.posts.reverse();
}),
err => {
console.log(err);
return false;
};
});
Both components use posts service:
getPosts() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.get('http://localhost:3000/posts/fetch', {headers: headers})
.map(res => res.json());
}
addPost(post) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
this.subject.next({post});
return this.http.post('http://localhost:3000/posts/add', post, {headers: headers})
.map(res => res.json());
}
fetchPost(): Observable<any> {
return this.subject.asObservable();
}
As you can see, I use Observable methodology to process data between components. The problem which I have is that post list is updating after I add post to database, but without the last added post. So if I would add two posts - 1) 'abc' and 2) 'cba', after send 'abc' anything happened, and when I add 'cba' list will be updated with 'abc' on the top.
I think the case is that addPost method is calling after getPosts and fetchPost.
How to fix that?

Related

Ionic calling submit method in another method is not working properly

Below mentioned is my submit method will post some data to the server when I click on a submit button.
it is working well when the action is performed manually. but I don't want to press submit button every time I want to call this after input texts were filled for this I'm calling this method in another method at that time it is not posting anything it is giving undefined can anyone help me on this
start() {
SMSReceive.startWatch(
() => {
document.addEventListener('onSMSArrive', (e: any) => {
var IncomingSMS = e.data;
this.smsaddress = IncomingSMS.address;
this.smsbody = IncomingSMS.body;
if (this.smsbody.includes("HELLO") || this.smsbody.includes("HI")) {
alert("Data : " + this.smsbody + this.smsaddress);
const obj={
smsbody:this.smsbody,
smsaddress:this.smsaddress
}
this.submit(obj);
} else {
alert("resetting")
this.resetdata();
}
})
},
() => { console.log('watch start failed') }
)
}
submit(msg) {
let headers = new Headers();
headers.append('content-Type', 'application/json');
this.http.post(this.ip + "/api/route", { headers: headers }).pipe(map(res => res.json()))
.subscribe(data => {
alert(JSON.stringify(data));
this.presentToast('Message has been submitted successfully', false, 'bottom');
this.resetdata();
})
}; ```
You forget to pass data in post request
submit(msg) {
let headers = new Headers();
headers.append('content-Type', 'application/json');
this.http.post(this.ip + "/api/route",msg, { headers: headers },).pipe(map(res => res.json()))
.subscribe(data => {
alert(JSON.stringify(data));
this.presentToast('Message has been submitted successfully', false, 'bottom');
this.resetdata();
})

Data does not update in view

I am creating an update function in my ionic 4 frontend which has a form to update user info. When I try to change the name, for example, it is updated in the database but is not displayed in the view through interpolation unless I logout and log back in. Here is my update method in the frontend.
updateInfo() {
if (!this.updateForm.valid) {
this.invalidUpdate();
} else {
if (!(this.name === "")) {
var nameObj = {
name: this.name
};
this._userService.updateName(nameObj).subscribe(
data => {
console.log(data);
this.getUserNamePoints();
},
error => {
this.updateFail();
}
);
}
};
this.getUserNamePoints();
}
}
And here is the method updateName(name) in the service
updateName(name) {
var headers = new Headers();
headers.append(
"Authorization",
"Bearer " + this._authService.getAuthorizationToken()
);
headers.append("Content-Type", "application/json");
return this.http
.post(environment.apiUrl + "/user/updateName", name, {
headers
})
.map(res => res.json());
}
This is the method getUserNamePoints() which is also called in the constructor:
getUserNamePoints() {
this._authService.getPoints().subscribe((res: any) => {
this.current = res.data;
this.clientName = res.name;
});
}
And here is the interpolation I am performing:
<h2>
<ion-text color="secondary" style="font-weight:bold">
Hello, {{ clientName }}!</ion-text
>
</h2>
This is my backend method:
module.exports.updateName = function(req, res, next) {
User.findByIdAndUpdate(
req.decodedToken.user._id,
{
$set: req.body
},
{ new: true }
).exec(function(err, updatedUser) {
if (err) {
return next(err);
}
res.status(200).json({
err: null,
msg: "Name was updated successfully.",
data: req.decodedToken.user.name
});
});
};
I think the problem is in your backend. I can see that you are sending the data from the decoded token and the token is encoded when you login, so it does not have the updated data.
res.status(200).json({
err: null,
msg: "Name was updated successfully.",
data: req.decodedToken.user.name
});
Can you show me how are you retrieving the data of the user from your backend when you call the method "getUserNamePoints();" ? Are you looking for the user data in your database or in the decoded token?

MEAN Stack: post method is not reflecting in database

I'm trying to pass some data through HTTP post method but it is not reflecting in the database.
This is code.
addJobList(jobitem) {
let headers = new Headers();
headers.append('Content-Type','application/json');
var selected = {
companyTitle : jobitem.company,
jobTitle : jobitem.jobtitle,
location : jobitem.location
}
console.log(selected);
this.http.post('http://localhost:3000/api/appliedjobs', JSON.stringify(selected),{headers: headers})
.map(res => res.json());
}
//getting jobs form back-end
getAppliedjobList() {
if (this.jobslist) {
return Promise.resolve(this.jobslist);
}
return new Promise( resolve => {
let headers = new Headers();
headers.append('Content-Type','application/json');
this.http.get('http://localhost:3000/api/appliedjobs',{headers: headers})
.map(res => res.json())
.subscribe(data => {
this.jobslist = data;
resolve(this.jobslist);
});
});
}
I've data in in the object called selected.
{companyTitle: "Facebook", jobTitle: "System Engineer", location: "torinto,canada"}
data from console. But this data is not get inserted into the database.
This is the code in my routes folder.
const jobList = require('../models/jobList');
router.post('/appliedjobs', function(req,res) {
console.log('posting');
jobList.create({
companyTitle: req.body.companyTitle,
jobTitle: req.body.jobTitle,
location: req.body.location
},function(err,list) {
if (err) {
console.log('err getting list '+ err);
} else {
res.json(list);
}
}
);
});
I'm not getting any error just the data is not getting inserted into the database.
This is my model
var mongoose = require('mongoose');
const joblistSchema = mongoose.Schema({
companyTitle: String,
jobTitle: String,
location: String,
});
const JlSchema = module.exports = mongoose.model('JlSchema',joblistSchema,'joblist');
You don't need to encode your data like in this example and you must return your this.http.post.
addJobList(jobitem) {
let headers = new Headers();
headers.append('Content-Type','application/json');
const selected = {
companyTitle : jobitem.company,
jobTitle : jobitem.jobtitle,
location : jobitem.location
}
return this.http.post('http://localhost:3000/api/appliedjobs', selected, { headers: headers })
.map(res => res.json());
}
To use it you need to subscribe to your addJobList method, http.post is an observable and needs to be subscribed to make the http call :
addJobList(theJobItem).subscribe(data => console.log(data));

http post subscription and try catch

I use Angular2's http.post and sometimes the headers are not send to the CORS server. So I want to try till the request succeeds. But this code hangs in an endless loop?
var headers = new Headers();
headers.append('Content-Type', 'text/plain');
this.again = true;
while (this.again==true) {
http.post('https://localhost:44300/account/getip', "", { headers: headers })
.subscribe(
(res2) => {
try {
this.ip = res2.json();
this.ipstr = this.ip.replace(/\./g, '-');
this.again = false;
}
catch (err) {
console.error(err);
}
}
);
}
If you want to catch errors from request you could either:
Use the second callback of the subscribe method:
http.post('https://localhost:44300/account/getip', "", { headers: headers })
.subscribe(
(res2) => {
(...)
},
(error) => {
(...)
}
);
}
Use the catch operator:
http.post('https://localhost:44300/account/getip', "", { headers: headers })
.catch((error) => {
(...)
})
.subscribe(
(res2) => {
(...)
}
);
}
Regarding retrying requests, you could leverage the retry operator this way (with a timeout one):
this.http.get('https://localhost:44300/account/getip',
{ search: params })
.retryWhen(error => error.delay(500))
.timeout(2000, return new Error('delay exceeded'))
.map(res => res.json().postalCodes);
You can see the use of delay to wait for an amount of time before executing a new request...
This article could interest you as well:
https://jaxenter.com/reactive-programming-http-and-angular-2-124560.html
You can use the retry operator:
http.post('https://localhost:44300/account/getip', "", { headers: headers })
.retry(3)
.subscribe((res2) => {
this.ip = res2.json();
this.ipstr = this.ip.replace(/\./g, '-');
})

Async and localStorage not working properly

So I'm using React with React-Router.
I have a onEnter hook which checks if the user is authenticates yes/no and executes the desired action.
export function requireAuth(nextState, replaceState) {
if (!isAuthenticated()) {
if (!Storage.get('token')) replaceState(null, '/login');
return delegate().then(() => replaceState(null, nextState.location.pathname));
}
if (nextState.location.pathname !== nextState.location.pathname) {
return replaceState(null, nextState.location.pathname);
}
}
When the token is expired I call a delegate function which looks like:
export function delegate() {
const refreshToken = Storage.getJSON('token', 'refresh_token');
return getData(endpoint)
.then(res => {
Storage.set('token', JSON.stringify({
access_token: res.data.access_token,
refresh_token: refreshToken,
}));
});
}
The delegate function indeed refresh the tokens in the localStorage. But the requests after the replaceState are not using the updated token, but the previous one. I think this is a async issue, someone knows more about this?
Edit: The function where I use the token:
function callApi(method, endpoint, data) {
return new Promise((resolve, reject) => {
let headers = {
'Accept': 'application/json',
'X-API-Token': Storage.getJSON('token', 'access_token'),
};
const body = stringifyIfNeeded(data);
const options = { method, headers, body };
return fetch(endpoint, options)
.then(response =>
response.json().then(json => ({ json, response }))
).then(({ json, response }) => {
if (!response.ok) {
reject({ json, response });
}
resolve(json);
}).catch((error, response) => {
reject({ error, response });
});
});
}

Categories

Resources