Load with loadStrings() a text file saved with saveStrings()?


#1

Hi everyone. I’d like to write two demonstration codes for my students that makes the following operations:

#1 save a list of strings into a text file with saveStrings()
#2 open this text file and read/transfer the saved strings back into a new list of strings

See the codes below. The problem is that through saveStrings() the browser creates the files into an unknown internal folder on local drive. And I don’t see in loadStrings() function a way to give it an argument asking it to load a file from this same folder used by the browser.

Any idea? Thanks a lot for your light! :smiley:

Laurent

a. save strings into .txt file

var sentence = 'Everybody in this country should learn to program as it teaches you how to think';
var words = split(sentence , ' ');

saveStrings(words , 'words.txt');

b. read strings from .txt file

var words;

function preload(){

   words =loadStrings('words.txt');

}


#2

Unfortunately, it’s not possible to specify a location to download a file to in a browser, and the text file will be downloaded to your downloads folder (or where ever you set the location).

If you’re using the program just for yourself, you can find the path of where words.txt if download to, and put the absolute path into loadStrings();. (But others locations will be different so it may not work on others devices.)


#3

What about adding a file selector to choose the file you want to upload to your sketch? I haven’t tried, but here there are some examples (maybe the one using vanilla JS):


Would that help?


#4

We can also use the p5.Element::drop() method: :droplet:

Or a more “traditional” p5::createFileInput(): :open_file_folder:


#5

Thanks a lot for your replies and suggestions Sarah and hamoid :smile:!

What I don’t understand is the prupose of the saveStrings() function. What is the interest for a sketch or a JS application to save data into a file that cannot be used afterwards? I can imagine that this function uses the Javascript FileSystem API. But apparently this API makes it possible not only to save data into a temporary file but also to get back these data reading the file. Even if the file is only available during the user session.

What I’d like to make with saveStrings(), saveJson() or saveTable() is to simulate a user registering and login web page: user completes a form with its username or e-mail address and a password. Then the user data is saved or added to a file. Afterwards the user can use his data to login. The idea is to illustrate how registering and login pages work.

But if loadStrings(), loadJson() loadTable() are not the asymetric functions of saveStrings(), saveJson() or saveTable(), it’s not possible to do this with simple code (this illustration or exercice is for beginners learning preogramming). And I don’t see the goal of loadStrings(), loadJson() loadTable() if they save data into files located we don’t know where into a virtual space of the browser (see

https://stackoverflow.com/questions/8282087/filesystem-api-where-are-the-files-and-folders-located)

that cannot be used afterwards.

Any idea of the purpose of saveStrings(), saveJson() or saveTable()? Would it possible for p5.js developpers to improve loadStrings(), loadJson() loadTable() functions in the futur in order for those functions to be able to load files saved with saveStrings(), saveJson() or saveTable() into virtual memory space of the browser?

Thanks for your precious lights about this!

Laurent


#6

Hi @Laurent :slight_smile: Interesting feedback! I never thought about it that way, but I think you are right that the save and the load functions are not symmetric. That doesn’t mean they are not useful, but they are indeed different to their Processing counterparts in a way.

I made here an example with saveJSON:
https://editor.p5js.org/abe/sketches/SJXNZI6C7

So one reason to use the save functions would be to save data produced by your application. The data would be saved to the users disk. Even if you could not upload it back to the application it can still be useful. For instance, you can create a program that generates random poems, and you can download them as text files to your device so you can read them later. Or you could create other kind of useful JSON or Table data.

As I show in the example, it is possible to upload the data back to the application. I’m not an expert, so I hope there’s a simpler approach than what I did, because that decodeBase64 function does not look very nice. When you upload images I think they are automatically decoded, but not so with text files. Maybe someone can suggest a better approach.

But in any case, it works: you can create designs, download them to your computer and upload them back to the sketch.

What’s interesting is what you mentioned: that they are not symmetric. Because the load functions take URLs, so you can load stuff found online, but not easily from your own computer, because the files in your computer can’t be accessed by a URL, unless you have a running web server. So can someone confirm if this diagram is true?

Based on the log-in-screen example you mention, I think the load/save approach is not what you are looking for. You would want the data to be saved on a server, not on client side. p5.js is a client side library, and runs on the clients computer. If I’m not misunderstanding, you would want to save the user input on a server. That would require setting up a web server (maybe with node.js) which can accept, store and retrieve the data sent by users. Is that the case?


#7

Hi amoid! Thanks a lot for all your explanations and the json example. Yes, the decodeBase64() could frigthen a “little bit” beginners :slight_smile: You’re right: if ones wants to make a real example of a registering and login page ones should use a service side script (JS, PHP) and a database on server side too. But that’s not my intention here because it could take for a very long time before a beginner learns all the necessary skills to be able to write such a project or even simply understand its code (client / server paradigm, database modeling, SQL, web application, …)

My idea is to make make simple code in order to simulate this registering and login process on client side only with p5.js and html. In this simulation, a simple array, list or json table saved into a file could simulate a database table.

The process would be the following:

  1. the user register with an html form
  2. the application gets the user data from the form fields
  3. the user data are added to a list or json table
  4. the list or table is saved into a file on client side
  5. the user goes to the login page and enter username and password into login form
  6. the application reads the file and import back the user data
  7. the application compares user password to validate or not the login

But of course, during the same session, we can pass over step #4 and #6. And as an alternative we can give the opportunity to user to download the table as a file in order to save it to the sketch folder (assets) if he doesn’t want to loose the data he entered. This would replace step #4 that would be done mannualy. And afterwards the step #6 could be possible for the login.

If saveStrings, saveJson, … functions could also works as symetric functions for loadStrings, loadJson, … it would great too. Because for beginners (and non beginners: I’ve been programming for more than 36 years…) the symetric names used for those functions are confusing concerning what they really do and their roles, leaving to think they have similar contracts.

We’re gonna start a definitely new cs course for the first time in all our highschool and there are very long discussions and even ‘struggle’ concerning the choice of programming languages. For some people, teachers should be able to choose the langage they want to use with their students, for others they should not and the language should be imposed and be the same for everyone, in the interest of students. Others arguments we should let the choice between two easy langages for beginners with close syntax: Python and Javascript. And even that it would be a chance for students to discover it exists differents langages and that it’s not so difficult to pass from one to another for the basic concepts (variables, loops, functions, etc) but that the main difference is that all languages does not provide the same libraries and there are some specialized to manipulate somes technologies and some for other technologies (typically web, roborts, etc).

The problem is that the mainstream idea today is still to impose one common language to all teachers. And most of people will vote for Python. It’s a very good language but mainly a ‘desktop’ language (of course it can be used on server side but for beginners it has no really interest). If Python is choosen and imposed, we can forget to use p5.js (a very creative one that could motivate our students because they live every hour in the world of the the web) in order to teach programming to our student.

So now we are trying to convince that the best way for everyone would be to accept both Javascript and Python in our courses. And we’re writting a comparison table showing how you write fundamentals (variables, loops, test, etc) in both languages to demonstrate that difference are so minors that it wouldn’t be serious a problem for a student having learnt fundamentals to pass from language to another if using same libraries, what can be the case with Processing (we could even extends our table to Java…) But when we compare Javascript and Python, ones could says that with Javascript it’s not possible to save locally data into a file and read it back afterwards, what is very easy with Python in dekstop application.

That’s one of the reason why I try to find a solution to enable a JS program to be able to do the same in an easy way and I hoped that saveStrings and loadStrings() could provide this way…


#8

There could be something interesting here… Maybe ideas for integration of new beginners oriented functions into p5.js.


#9

Hi @Laurent, the Mozilla Developer Network documents are often excellent at explaining any web technology. According to this page using localStorage is very very simple, no set up required, and it allows you to store and retrieve data. One question though: do you plan to use p5.js directly from the file system (url looks like file://...) or hosted in a server (url looks like http…)? Both options have different security models…

The reason the web browser is limited regarding to access to your files and folders as you probably know is about security. You don’t want web pages to be able to write and read files at will, and a page running p5.js is still a web page. Working on the browser has it’s advantages (it’s easy to show to the world your creation) but it also has its limitations (sometimes security related, but also limited in regard to access to hardware interfaces).


#10

Hi hamoid. Thanks for your explanation about the difference between local and web storage with p5.js skectch! Well, the idea is mainly to let students make and execute their sketches on a local web hosting context (that is running p5.js sketch on local computer transformed into web server thanks to Processing IDE or XAMPP for instance). When a sketch is finished and working, then it can be published on a real web server to be shared over Internet with friends and everyone interested. It could be more motivating than making a Python or Java sketch, put it on a server, telling interested people they can download the sketch to try it but before they should have to download and install Processing + open and execute the sketch into Processinng…)

I understand the necessity of security for accessing local files from a JS application included into an html page. But what would be very nice would be the ability for p5.js to save data into files of the browser workspace and then reading back these data. With very simple functions, as in the p5.js spirit. The standard client-side storage API are nice and could do the job. But not really simple to be used for true beginners, compared for instance to native saveStrings() and loadStrings functions of p5.js. Such extension in a new version of p5.js could be an new advantage for beginners :slight_smile:


#11

Maybe adding a boolean argument to load/save methods to useLocalstorage would help?

saveStrings(myList, "myfile", "txt", true); // saves to local storage
loadStrings("myfile.txt", cb, err, true); // loads from local storage

There’s many ways to achieve that, not sure what’s the most clear. A global method to enableLocalStorage()? (that’s less flexible, as you can’t combine remote and local). Or new methods? saveStringsLocal()?


#12

I would tend to the arguments. In that way, one can become aware that one can save and load files to and from different storage area. With overloading (function accepting standard signature and a new extended signature with the boolean argument), the classic way to call the function will still be avalaible in parallel with the extended, so that would mean no function depreciation and guaranteed compatibility with a previous versions of p5.js.