Ionic 1 - ngCordovaNativeStorage issue? - javascript

how's it going?
I've using this plugin for a long time, but today I needed to do some notifications in my app. I need to store my data in device and then, when I got internet connection, I'll send this for my servers. But ok, this is not important.
What I'm trying to do is:
Get my data from server;
Store my data in device using nativeStorage;
Getting data and putting in my storage
myFactory.getMyData().then(function(success) {
$cordovaNativeStorage.setItem("mydata", success);
}, function(err) {...});
OK, my data was correctly stored. Next I'll loop in thru this data and show in view.
$cordovaNativeStorage.getItem("mydata").then(function (success)
{
for (var i in success)
{
$scope.myData.push(success[i]);
}
}, function (err){
getMyData(); // function who will get my data from server
});
OK until now.
Next I'll send this data to another view and show my data. But when I do ANY modifications in that data (even if I change directly in object or in nativeStorage), that modification do not persists if I back to the main view.
$cordovaNativeStorage.getItem("myData").then(function (success){
success[myIndex].anyProperty = 'abc';
});
Is that a bug or am I not understanding something?

When you're calling $cordovaNativeStorage.setItem(), Native storage actually save JSON string rather than JSON object.Same with $cordovaNativeStorage.getItem(), it will return JSON string. Thus, you must parse it first before manipulating the object .
$cordovaNativeStorage.getItem("myData").then(function (jsonString){
if (jsonString) {
var jsonObj = JSON.parse(jsonString);
jsonObj.anyProperty = 'abc';
}
});

Related

How to get data from back end side, to use it in the browser side?

I am new to programming, and I heard that some guys on this website are quite angry, but please don't be. I am creating one web app, that has a web page and also makes som ecalculations and works with database (NeDB). I have an index.js
const selects = document.getElementsByClassName("sel");
const arr = ["Yura", "Nairi", "Mher", "Hayko"];
for (let el in selects) {
for (let key in arr) {
selects[el].innerHTML += `<option>${arr[key]}</option>`;
}
}
I have a function which fills the select elements with data from an array.
In other file named: getData.js:
var Datastore = require("nedb");
var users = new Datastore({ filename: "players" });
users.loadDatabase();
const names = [];
users.find({}, function (err, doc) {
for (let key in doc) {
names.push(doc[key].name);
}
});
I have some code that gets data from db and puts it in array. And I need that data to use in the index.js mentioned above, but the problem is that I don't know how to tranfer the data from getData.js to index.js. I have tried module.exports but it is not working, the browser console says that it can't recognize require keyword, I also can't get data directly in index.js because the browse can't recognize the code related to database.
You need to provide a server, which is connected to the Database.
Browser -> Server -> DB
Browser -> Server: Server provides endpoints where the Browser(Client) can fetch data from. https://expressjs.com/en/starter/hello-world.html
Server -> DB: gets the Data out of the Database and can do whatever it want with it. In your case the Data should get provided to the Client.
TODOs
Step 1: set up a server. For example with express.js (google it)
Step 2: learn how to fetch Data from the Browser(Client) AJAX GET are the keywords to google.
Step 3: setup a Database connection from you Server and get your data
Step 4: Do whatever you want with your data.
At first I thought it is a simple method, but them I researched a little bit and realized that I didn't have enough information about how it really works. Now I solved the problem, using promises and templete engine ejs. Thank you all for your time. I appreciate your help)

Most browsers do not 'remember' the result of Ajax request when going back to page

I have a page with a form that gives a user the option to filter a list of objects (programs) by selecting options. For example, they could select the option architecture to show only the programs which contain that subject. An AJAX-request is sent to the server, which then returns the results. So far, everything works.
My problem: in some browser when someone clicks to go to another page and then goes back to the page where the form is, the results are reset, although the form selection(s) are still visible. In Chrome this is a problem, whereas in Firefox this does not happen. On this page you can see a live example.
My JavaScript AJAX post-request looks like this:
let sendQuery = () => {
let programsList = document.getElementById('programs-list');
axios.post('/programs/getByFilter', filter )
.then(function (response) {
programsList.innerHTML = response.data;
})
.catch(function (error) {
console.log(error);
});
}
And then in PHP (I use Symfony):
/**
* #Route("/getByFilter", name="program_get_by_filter")
*/
public function returnProgramsByFilter(Request $request, SearchHelper $searchHelper)
{
$jsonFilter = $request->getContent();
$filter = json_decode($jsonFilter, true);
// the query is done here.
$programs = $searchHelper->findByFilter($filter);
return $this->render('program/programs_ajax.html.twig', [
'programs' => $programs ]);
}
Now I have looked for similar questions and found this one and this one, but I haven't been able to solve the problem. Initially I tried to send the request as a GET-request instead of a POST-request, but the data I send is JSON and I did not manage to make it work. I am not really sure if that has to do with the JSON or not. My understanding of JS is really poor. Then I tried with a session variable like so:
$jsonFilter = $request->getContent();
$filter = json_decode($jsonFilter, true);
$session->set('filter', $filter);
And then:
if($session->has('filter')){
$programs = $searchHelper->findByFilter($session->get('filter'));
} else {
$programs = $programRepository->findAll();
}
This does not really work either because the original options will be overwritten when going back and making a new selection. Also, with my JS I show the current filters that are being used and the number of results. That's gone too.
Is there a JS solution or should I try to fix this in PHP?
Update:
I have been able to set filter as a cookie every time an ajax call is made by making it a string with JSON.stringify(filter) and then I get it and use it with:
// Getting the cookie, parsing it and running the query.
var filterCookie = getCookie('filter');
if (filterCookie) {
var objectCookieFilter = JSON.parse(filterCookie);
let programsList = document.getElementById('programs-list');
axios
.post('/programs/getByFilter', objectCookieFilter )
.then(function (response) {
programsList.innerHTML = response.data;
})
.catch(function (error) {
console.log(error);
});
}
This will re-run the last query that was set in the cookie. The problem that remains though is that all the filter-badges are set on a change event of the checkboxes and I cannot figure out how to show them based on the cookie (or perhaps some other way?)

Express with JSON Data Control

I use lowDB dependency to control the JSON Data with Express and actually it works. But there is a bug and I cannot find how to solve it.
I create /create page to add information in JSON file and it contains 4 form and submit button.
And In express I code like this. each forms data will save it in variable and push with lowdb module.
router.post('/post', function (req, res) {
let pjName = req.body.projectName;
let pjURL = req.body.projectURL;
let pjtExplanation = req.body.projectExplanation;
let pjImgURL = req.body.projectImgURL;
console.log(pjName);
db.get('project').push({
name: pjName,
url: pjURL,
explanation: pjtExplanation,
imgurl: pjImgURL
}).write();
console.log(db.get('project'));
console.log(db.get('project').value());
res.redirect('/');
})
And it works well. But when I modify the JSON file myself (ex. reset the JSON file) and execute again. It shows the data that I reset before. I think in this app somewhere saves the all data and show save it in array again.
And When I shutdown the app in CMD and execute again, the Array is initialized.
As you may already know the lowdb persist the data into your secondary memory (hdd), and may return a promise depending on your environment when you call write method.As mentioned in the doc
Persists database using adapter.write (depending on the adapter, may return a promise).
So the data may be still getting write when you read them, so the old data is queried. Try this,
db.get('project').push({
name: pjName,
url: pjURL,
explanation: pjtExplanation,
imgurl: pjImgURL
}).write().then(() => {
console.log(db.get('project'));
console.log(db.get('project').value());
});

MeteorJS - No user system, how to filter data at the client end?

The title might sound strange, but I have a website that will query some data in a Mongo collection. However, there is no user system (no logins, etc). Everyone is an anonymouse user.
The issue is that I need to query some data on the Mongo collection based on the input text boxes the user gives. Hence I cannot use this.userId to insert a row of specifications, and the server end reads this specifications, and sends the data to the client.
Hence:
// Code ran at the server
if (Meteor.isServer)
{
Meteor.publish("comments", function ()
{
return comments.find();
});
}
// Code ran at the client
if (Meteor.isClient)
{
Template.body.helpers
(
{
comments: function ()
{
return comments.find()
// Add code to try to parse out the data that we don't want here
}
}
);
}
It seems possible that at the user end I filter some data based on some user input. However, it seems that if I use return comments.find() the server will be sending a lot of data to the client, then the client would take the job of cleaning the data.
By a lot of data, there shouldn't be much (10,000 rows), but let's assume that there are a million rows, what should I do?
I'm very new to MeteorJS, just completed the tutorial, any advice is appreciated!
My advice is to read the docs, in particular the section on Publish and Subscribe.
By changing the signature of your publish function above to one that takes an argument, you can filter the collection on the server, and limiting the data transferred to what is required.
Meteor.publish("comments", function (postId)
{
return comments.find({post_id: postId});
});
Then on the client you will need a subscribe call that passes a value for the argument.
Meteor.subscribe("comments", postId)
Ensure you have removed the autopublish package, or it will ignore this filtering.

Meteor - Server-side API call and insert into mongodb every minute

I am in the process of learning Meteor while at the same time experimenting with the TwitchTV API.
My goal right now is to call the TwitchAPI every minute and then insert part of the json object into the mongo database. Since MongoDB matches on _id and Twitch uses _id as its key I am hoping subsequent inserts will either update existing records or create a new one if the _id doesnt exist yet.
The call and insert (at least the initial one) seem to be working fine. However, I can't seem to get the Meteor.setTimeout() function to work. The call happens when I start the app but does not continue occurring every minute.
Here is what I have in a .js. file in my server folder:
Meteor.methods({
getStreams: function() {
this.unblock();
var url = 'https://api.twitch.tv/kraken/streams?limit=3';
return Meteor.http.get(url);
},
saveStreams: function() {
Meteor.call('getStreams', function(err, res) {
var data = res.data;
Test.insert(data);
}
}
});
Deps.autorun(function(){
Meteor.setTimeout(function(){Meteor.call('saveStreams');}, 1000);
});
Any help or advice is appreciated.
I made the changes mentioned by #richsilv and #saimeunt and it worked. Resulting code:
Meteor.startup(function(){
Meteor.setInterval(function(){Meteor.call('saveStreams');}, 1000);
});

Categories