Problem with inserting data to app's own container

api

#1

Hi. I wrote a simple test app, where I get app’s home container and try to insert an entry to it. But that does not seem to work - pushing read button, then save and then read again makes no difference between reads - no entry seems to be added to md. Can anyone check what I’m possibly doing wrong?

I’ve abstracted all original API mess to safe_api.js file, so the code may not look familiar to you, but possibly cleaner :slight_smile:


JS Wrapper or Higher Level API
I think I'm missing something fundamental
#2

I’d suggest to try doing it in safe://webapi.playground and see if it works there.


#3

Hi @loziniak

I actually just posted about looking for API wrappers. I started on my own wrapper, also called safe_api.js, but I’d rather collaborate than write it all by myself. Here’s my thread:

I will give your code a look a little bit later today and add any comments to GitHub.


#4

As an aside, I have had some problems debugging with the SAFE Browser. Someone else posted about that, too:

Here’s a snippet of code I have been using to debug within the browser:

// Status element for logging.
var status_el = null;

function set_logger(element_id) {
  status_el = document.getElementById(element_id);
  return status_el;
}

// Log text to status element.
// Returns the status element.
function log_status(text) {
  if ((status_el === undefined) || (status_el === null)) {
    return;
  }

  if ((status_el.tagName === 'UL') || (status_el.tagName === 'OL')) {
    // Log using LIs if the element is a list.
    var item = document.createElement('LI');
    item.textContent = text;
    status_el.appendChild(item);
  } else {
    // Replace the element's textContent otherwise.
    status_el.textContent = text;
  }
  return status_el;
}

So I call set_logger(some_id); in my page JS and have some element with id="some_id". If it is a UL or OL, LIs will be appended to the DOM for each message, giving you a history. If the element is anything else, it’s textContent is overwritten.


#5

Okay. I downloaded your code from GitHub at commit 7f3d8827 (which is your current master).

I added a UL for logging to your HTML. I added the above debug code to test.js and set console.log = log_status. I uploaded the entire directory using the Web Hosting Manager. I visited test.html using the SAFE Browser.

The first thing I noticed upon load is that permissions are requested for own container. That’s good! That should mean both initialiseApp and authoriseAndConnect work. The following got logged to console.log, now made incredibly visible thanks to the weird log_status workaround I built in:

SAFEApp instance initialised and handle returned:
[object Object]

The first message is clearly identifiable. I think the second message is from line 20 (you logged the containers permission object). Notice that Network state changed to: from line 14 does not appear. Might be something to look at.

I clicked the Save button. The following was added to my log:

inserted data.
psHandle: 526e1c0525c8b711d8b20106ddda73241c3570e76b9fc3990588519b41a4901b
permissions set.
COMMITED.

That sounds like a successful setting. I didn’t look into it with any depth, mind you.

I clicked the Load button. The following was added to my log:

[object Object]

That appears to be the mdObj from line 52. So I guess that works too. Again, I’m just skimming.

Here’s a fun fact! On line 26 you set messageDisplay. It looks like you never used it, so nothing will output there.

Hope that helps. It looks like things are working. I plan to see how far your library can get me in the stuff I need to get done, so I’ll be looking more in depth at that time. I’ll file Issues and PRs to GitHub, other notes I’ll publish here.

EDIT: all line numbers are for test.js.


#6

Hello, @BryanB! Thanks very much for extensive testing and feedback.

The problem is visible when you look into the logged object. When you log it in HTML ul tag it’s visible as text, but if you look into the console, you can click the object and see it’s internals (entries, permissions, name, tag etc.). Then you can see that on the second Read, after the Save number of entries in md object does not change.

I changed my code to use mutations and it works now (commit 630d5fc6ec7c). This leads me to conclusion that 1) I use safeMutableDataEntries.insert() in a wrong way, or 2) there is a bug in the browser API.


#7

I created a pull request with a unit test for this case:


#8

@BryanB, do you have any code of your wrapper available online? I’d be happy to colaborate on that. But my concern is that eventually MaidSafe team will create some developer-friendly library, thus making our work irrelevant :slight_smile: There even was a pull request by @bochaco: https://github.com/maidsafe/rfcs/pull/213 , I wonder why it’s closed. So I try to not give too much effort to develop the wrapper, just enogh to make it easy for me to develop an app.


#9

@loziniak

I haven’t uploaded any of my code anywhere yet, because I can’t get a darn thing to work :frowning:

I’m using the 0.3.0 API and basically spinning my tires for 2-3 days straight. I gave your wrapper a much closer look. I tried to get the code for your saveButton and readButton a try on my own test site. No errors with saveButton, but readButton always came back with empty entries. I started going through the API trying to figure out what you missed: maybe crypto can’t be null even though docs say it can, maybe ownContainer.getPermissions() isn’t right and you need newPermissions() (which I added to your lib during my test period). Nothing. I couldn’t get data entered with put to ever come back out the other side. I gave up.

Yeah, you’re right about true console.log versus textContent in an element. Does console.log actually work for you? I’m using SAFE Browser 0.6.0 (alpha-2) built for mocknet and my console is some weird output and it inspects the browser itself, not the content of the web page. Nothing logged in the web page ever appears. I linked this problem in an earlier comment. Just curious to hear if someone out there is running a mocknet capable alpha-2 browser without issue.

Once I gave up on your code, I wanted to find some code that actually integrates the API calls together to makes something happen, and the markdown editor looks like it has some simple, modular code:

https://github.com/maidsafe/safe_examples/tree/master/markdown_editor

I did some light modification of that code (replaced exports and imports with regular definitions). They have some quite nice high level functions like saveFile() and getFileVersions(). I can’t get that to work either. It’s not worth getting into details here, but basically, I have not been able to get anything working in SAFE net. I’m not a useful source for help, so I’m gonna tap out of this thread until I can make anything at all work.


#10

@loziniak

@bochaco pointed these code examples out to me:

https://github.com/maidsafe/safe_examples/releases/download/0.13.0/examples.html

I tested them in my browser and it’s the first thing I’ve gotten to work on my mocknet. I suspect your problem is the precise order you’re making your API calls. The API gives everything piece-by-piece but documentation on how to put those pieces together is either lacking or I haven’t found it. These examples certainly fill in that gap, since they use the API calls, and they demonstrate the precise ordering of those calls.


#11

@drehb, I tried there and it also didn’t work. The sequence I used (without modifying any of the default code snippets):

safeApp: initialise
safeApp: authorise
safeApp: connectAuthorised
safeApp: getOwnContainer
safeMutableData: getEntries
safeMutableDataEntries: forEach
safeMutableDataEntries: insert
safeMutableDataEntries: forEach

Second “forEach” should give me something like “key1:value1”, but the output is the same as from the first “forEach”.


#12

@BryanB, i’ve searched safe_examples on GitHub, and only place where “safeMutableDataEntries.insert” is found is WebApiPlayground’s code snippet. Which unfortunately gives me the same result.


#13

Probably not helpful, but just in case, I’m using safeNfs.insert() (on the default container):

https://github.com/theWebalyst/remotestorage.js/blob/feature/safestore-backend-gd/src/safenetwork.js#L785


#14

I noticed the markdown editor in safe_examples is also using the safeNfs calls.

I’m getting the impression safeNfs is the way to manage constant data, as opposed to ImmutableData.


#15

Just in case anyone reading this thread doesn’t see this response from Josh on another thread:


#16

But when you use safeMutableDataEntries.insert instead of mutations, you dont’t call safeMutableData.applyEntriesMutation, do you?


#17

No, you don’t, you call window.safeMutableData.put instead.


#18

So when you want to simply insert a key to a MD this way, you have to “getPermissions” also, just to “put” them back? Not very usable. Also, a “put” could be useful to have in documentation then: http://docs.maidsafe.net/beaker-plugin-safe-app/#windowsafemutabledataentriesinsert


#19

Correct, and it might not even work as it may try to create the same MD again and thus failing. This is meant mainly for when you are creating the MutableData and setting it up with its initial set of permissions and data/entries rather than updating it which is when you should use mutations instead.


#20

@loziniak I wouldn’t say “not very usable”, more this is how low-level APIs work, and we need to build higher level APIs over top this drudgery so that new developers to the project (like you and me) aren’t immediately overwhelmed by the number of calls necessary to do logical tasks like “update the key with this value”.

Being the change one wants to see, it’s up to us to make that higher level API.

EDIT: I’m really happy with the JavaScript class you’ve made to manage the stateful information that does not easily pass through Promises. However, what you’ve written is still quite low level. As I work on my project, I intend to build on top of your work thus far, and I will make sure to share progress via GitHub. For now, I’m still dotting all my Is and crossing all my Ts to get some simple examples of my own working. Apparently there’s one part of Promise chaining I still don’t completely understand (just when I thought I had it down). Once I work through that, I’ll likely be sending a PR or two your way.