Not keeping the previous data in session array - express-session

I am working on an online food ordering project using MEAN full stack. On the server I am using an express session for persisting the data. I have declared an array session to store the array data in the session but it is not keeping the previous data -- it overwrites the existing value. Here is my code:
app.put('/addCart',function(req,res,next){
db.collection('product',function(err,productCollection){
var id = parseInt(req.body.id);
productCollection.findOne({_id:id},{},function(err, products){
var cart = req.session.cart || [];
if(req.session.cart == null){
req.session.cart = [{p_id: products._id, p_name: products.title, p_price: products.price,quantity:1}];
}
else{
cart.push({p_id: products._id, p_name: products.title, p_price: products.price,quantity:1});
}
return res.json(req.session.cart);
});
});
});
In the controller I am passing the id of each food item to the server.
Here is angular code:
app.controller('FoodCartController' , function($rootScope,$scope, $http,$routeParams){
$scope.addCart = function(food){
$http.put('/addCart',{id:food._id}).then(function(response){
console.log(response.data);
$scope.carts = response.data;
});
});
Please help me sort out this problem.

Related

How to add if else condition to data in Realtime Database in Flutter?

Currently, I am working on a Flutter project, which is a tricycle booking system. Right now, I want to implement the functionality of having life points for every account. I have thought of this for some time and I have decided to store a value in the real-time database in firebase, it is where I will be decrementing the life points every time a user cancels the booking. What I want to do right now, is to check if the value stored in lifePoints is equal to a certain value, if yes, then I will be placing some functions and restrictions in there. So, how do i get the data from realtime database using flutter and add conditions to it?
Any help will be much appreciated. Thank you!
If you want to read data from Firebase, the documentation on reading data is a great starting point.
From there comes this great example of reading data once:
final ref = FirebaseDatabase.instance.ref();
final snapshot = await ref.child('users/$userId').get();
if (snapshot.exists) {
print(snapshot.value);
} else {
print('No data available.');
}
And this example for listening for data, which provides both the current value right away, and then continues to listen for updates:
DatabaseReference starCountRef =
FirebaseDatabase.instance.ref('posts/$postId/starCount');
starCountRef.onValue.listen((DatabaseEvent event) {
final data = event.snapshot.value;
updateStarCount(data);
});
If you want to increment/decrement a value in the database, have a look at this example from the documentation on atomic increments/decrements:
void addStar(uid, key) async {
Map<String, Object?> updates = {};
updates["posts/$key/stars/$uid"] = true;
updates["posts/$key/starCount"] = ServerValue.increment(1);
updates["user-posts/$key/stars/$uid"] = true;
updates["user-posts/$key/starCount"] = ServerValue.increment(1);
return FirebaseDatabase.instance.ref().update(updates);
}
Or if you want to perform a more complex update of a value based on its current value, you'll want to use a transaction:
DatabaseReference postRef =
FirebaseDatabase.instance.ref("posts/foo-bar-123");
TransactionResult result = await postRef.runTransaction((Object? post) {
// Ensure a post at the ref exists.
if (post == null) {
return Transaction.abort();
}
Map<String, dynamic> _post = Map<String, dynamic>.from(post as Map);
if (_post["stars"] is Map && _post["stars"][uid] != null) {
_post["starCount"] = (_post["starCount"] ?? 1) - 1;
_post["stars"][uid] = null;
} else {
_post["starCount"] = (_post["starCount"] ?? 0) + 1;
if (!_post.containsKey("stars")) {
_post["stars"] = {};
}
_post["stars"][uid] = true;
}
// Return the new data.
return Transaction.success(_post);
});
As you might notice these are all code snippets from the documentation, all from the same page even. I recommend spending some time studying that documentation, and then trying to apply these to your own use-case. If you then run into problems while implementing the use-case, post a question with the minimal code that reproduces where you got stuck and we can probably help further.

Using variables or constants in nextjs api

I'm trying to use a constant in my API. This constant is an array where I can push or pop objects. I populate it through API calls. This is the code:
const washes = [];
export default async (req, res) => {
if(req.method === 'GET')
{
res.json({washes});
}
if(req.method === 'POST')
{
washes.push(req.body);
console.log(washes);
res.json({washes});
}
}
I make calls from the front-end to populate the array and to retrieve it. The problem is that, sometimes I get an empty array an sometimes I get the expected array. Or after a while I always get the empty array, like if it was restarted.
I deployed the application on Vercel.
Is there something I'm missing from the back-end functionality, or is it related to Vercel?. Last but not least is it a good practice to use variables or constants in back-end.?
You cant use an array as storage. You need to connect it to a database of sorts.
When you use this endpoint it will only retrieve the correct array sometimes, because it's stored in a temporary memory on the server.
Look into firebase if you easily want to setup up a project and store information in a database.
https://firebase.google.com/docs/web/setup
Another way is to use a .json file in the back-end
Read more here: https://jasonwatmore.com/post/2021/08/28/next-js-read-write-data-to-json-files-as-the-database
USER EXAMPLE
const fs = require('fs');
// users in JSON file for simplicity, store in a db for
production applications
let users = require('data/users.json');
export const usersRepo = {
getAll: () => users,
getById: id => users.find(x => x.id.toString() === id.toString()),
find: x => users.find(x),
create,
update,
delete: _delete
};
function create(user) {
// generate new user id
user.id = users.length ? Math.max(...users.map(x => x.id)) + 1 : 1;
// set date created and updated
user.dateCreated = new Date().toISOString();
user.dateUpdated = new Date().toISOString();
// add and save user
users.push(user);
saveData();
}
function update(id, params) {
const user = users.find(x => x.id.toString() === id.toString());
// set date updated
user.dateUpdated = new Date().toISOString();
// update and save
Object.assign(user, params);
saveData();
}
// prefixed with underscore '_' because 'delete' is a reserved word in javascript
function _delete(id) {
// filter out deleted user and save
users = users.filter(x => x.id.toString() !== id.toString());
saveData();
}
// private helper functions
function saveData() {
fs.writeFileSync('data/users.json', JSON.stringify(users, null, 4));
}

With Flutter/Dart How should I query data that doesn't build a widget?

I'm working on an app and I'm relatively new to this scene, but I'm running into some troubles when I'm looking to simply query some data.
I'm calling a function after someone logs in. The login function only sends the necessary information and I want to do a secondary ping to my server to get a little more user information, more than just verifying the login info.
getUser (userid) async{
List<Map<String, dynamic>> user=[] ;
var client = new http.Client();
try {
var req = await client.post(urlPath+'mobileGetUser', body: {'thisUserID': userid'});
var jsonResponse = convert.jsonDecode(req.body);
//print('Here: '+jsonResponse.toString());
var id = jsonResponse['id'] ?? '';
var joinDate = jsonResponse['joinDate'] ?? '';
var userEmail = jsonResponse['userEmail'] ?? '';
var displayName = jsonResponse['displayName'] ?? '';
var timezone = jsonResponse['timezone'] ?? '';
var verified = jsonResponse['verified'] ?? '';
user = [{'id': id}];
user = [{'joinDate': joinDate}];
user = [{'userEmail': userEmail}];
user = [{'displayName': displayName}];
user = [{'timezone': timezone}];
user = [{'verified': verified}];
return user
} finally {
client.close();
}
}
I'm used to working in PHP. In that language, I'd pass the JSON object or associative array back to the calling function and accessing the individual fields would be as simple as
$displayName = $user['displayName'];
But this isn't PHP. List types are a little strange to me still.
From my calling function, I try to test this with:
thisUser = getUser(userid);
print('Successful Login: Display name: '+thisUser.toString());
And I get a message of:
Successful Login: Display name: Instance of 'Future<dynamic>'
How can I access this data? I've tried a few ways to get it. Also, is there a better way to create my List? I'm definitely going through a few steps that feel unnecessary. I'm honestly like to just pass it the entire JSONresponse. I'm just a bit out of my depth.
You could do this:
thisUser = await getUser(userid);
print('after'); // this will print after getUser() finishes
If you don't await for getUser() to finish, then you'll receive a Future.
Another way would be to use that Future and add a listener to it, like this:
getUser(userid).then((value) {
print('after'); // this will print after getUser() finishes
thisUser = value;
});
print('before'); // this will print before getUser() finishes
This is assuming you aren't using this on widgets. Otherwise you could use FutureBuilder to detect when the Future finishes and show something.

Flutter, getting database records and then internet json

I have a simple table from which I'm fetching a list of records. Once I get the records, then I have to get information online for each of the records. The code to do this is as follows:
class UserStationList {
List<UserStationListItem> _userStations = [];
final StreamController<HomeViewState> stateController;
UserStationList({#required this.stateController});
Future fetchUserStations() async {
stateController.add(HomeViewState.Busy);
//Fetch stations from table.
List<Map<String, dynamic>> stations =
await UserStationDatabase.instance.queryAllRows();
//If there are no stations, return and tell the screen to display the no data message.
if (stations.length == 0) {
stateController.add(HomeViewState.NoData);
return;
}
//Loop through each of the stations in the list and build the collection.
stations.forEach((station) async {
UserStationListItem newItem =
await _getPurpleAirSiteData(station['_id'], station['stationid']);
_userStations.add(newItem);
});
//When done, let the screen know.
stateController.add(HomeViewState.DataRetrieved);
}
Future<UserStationListItem> _getPurpleAirSiteData(
int id, int stationId) async {
var response = await http.get('$kURL$stationId');
var data = json.decode(response.body);
return UserStationListItem(
id: id, stationId: stationId, stationName: data['results'][0]['Label']);
}
}
The problem that I am running into involves the futures. I am processing the loop in a forEach and calling into the _getPurpleAirSiteData function for each. Within that function I have to await on the http.get to bring in the data. The stateController.add(HomeViewState.DataRetrieved) function is being called and the function exits long before the loop is completed. This is resulting in the data not being available when the StreamBuilder that I have receiving the data is run.
How can I set this up so that the loop runs completely before calling stateController.add?
I would change this part of code to a list of Futures and await-ing on it.
//Loop through each of the stations in the list and build the collection.
stations.forEach((station) async {
UserStationListItem newItem =
await _getPurpleAirSiteData(station['_id'], station['stationid']);
_userStations.add(newItem);
});
To:
List<Future<UserStationListItem>> listOfFutures = [];
stations.forEach((station) {
listOfFutures.add(_getPurpleAirSiteData(station['_id'], station['stationid']));
});
var stationItems = await Future.wait(listOfFutures);
stationItems.forEach((userStationListItem) {
_userStations.add(userStationListItem);
});
What I am essentially doing creating a list of Futures with your server request. Then await on it which returns a list of item result Maintaining index, which in turn ensures that requests are completed before you hit statecontroller.add. You also gain a performance gain since all request are not going one by one and instead asynchronously. Then you just iterate through the future result and add it to your item list.

Meteor Collections.count() too slow on UI

I have done a Simple Publish/subscribe in my meteor project and whenever User lands on home page I have to show count of total users. Users are around 15000. Now in template helper I have code written a code as,
CLIENT-SIDE
Template.voters.helpers({
voters : function() {
return voters.find({});
},
count : voterscount
});
then on SERVER-SIDE
voters = new Mongo.Collection("voters");
voterscount = function() {
return voters.find({}).count();
}
Meteor.publish('voters', function() {
return voters.find({});
});
Meteor.publish('voterscount', function() {
return voterscount;
});
The output that I receive is that the count starts from 0 to 15000 on UI Which is irritating.
I don't want rolling up of the digits on UI and should show the static count on UI as 15000 whenever page refreshed.
Why is this so slow it. In production i will have around 10 million documents in collection. This is big drawback. Any help, please?
This is a good use case for a universal publication, i.e. one that is automatically sent to all clients.
Server:
stats = new Mongo.collection('stats'); // define a new collection
function upsertVoterCount(){
stats.upsert('numberOfVoters',{ numberOfVoters: voters.find().count() });
}
upsertVoterCount();
Meteor.publish(null,function(){ // null name means send to all clients
return stats.find();
});
var voterCursor = voters.find();
voterCursor.observe({
added: upsertVoterCount,
removed: upsertVoterCount
});
Then on the client you can get the voter count anytime with:
var nVoters = stats.findOne('numberOfVoters').numberOfVoters;
SERVER-publish.js
function upsertVoterCount(){
voterscount.upsert('numberOfVoters',
{
numberOfVoters : voters.find().count()
});
}
// null name means send to all clients
Meteor.publish(null ,function() {
upsertVoterCount();
return voterscount.find();
});
var voterCursor = voters.find();
voterCursor.observe({
added: upsertVoterCount,
removed: upsertVoterCount
});
LIB-collection.js
// define a new collection
voterscount = new Mongo.Collection('voterscount');
CLIENT-home.js
Template.voter.helpers({
count : function() {
return voterscount.findOne().numberOfVoters;
}
});