NAV

Giosg SDK

Authentication

Authentication with cookies

// Stars the authenticationn
let authSubscription = giosg.api.authenticateWithCookies().subscribe(auth => {
    console.log(
        "Successfully authenticated with user " + auth.user_id +
        " from organization " + auth.organization_id
    );
}, error => {
    console.error("Authentication failed!");
});
// Optional: you can terminate the access token renewal process
authSubscription.unsubscribe();

When your app starts, you need to call the authenticateWithCookies method at least once. This will make an HTTP request that exchanges your browser session cookies to an access token, that is stored to the SDK instance for the following requests.

This will also set up an access token renewal proccess! When the received access token is about to expire, a new one is retrieved. If you want to terminate the automatic renewal, then unsubscribe the subscription to the returned observable.

Observing the authentication

giosg.api.auth().subscribe(auth => {
    console.log(
        "Currently authenticated with user " + auth.user_id +
        " from organization " + auth.organization_id
    );
});

You usually want to do something with the “currently authenticated user”. The auth method returns an observable that emits the latest authentication information of the user. If the user is not yet authenticated, then the first item is emitted only after the first successful authentication is done.

See also the example how to stream resources of the authenticated user

Resources

Observe resource changes

// Start listening changes to a specific resource
giosg.api.streamResource('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b')
    .subscribe(organization => {
        // Emits the resource immediately when loaded, and later
        // all the changes to the resource.
    })
;

You can load the immediate state and then all the future updates for one specific resource. The stream completes only if the resource gets deleted from the collection.

If connection to the server breaks, the SDK will automatically reload the resource when the connection is re-established, and any missed updates will be emitted!

The stream will result in an error if the immediate load of the resource fails for any reason, e.g. the resource does not exist. However, after that the SDK will recover from connection problems automatically, reloading and emitting the resource if necessary.

Stop observing resource changes

// Start listening changes to the resource
let resourceStream = giosg.api.streamResource('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b');
// Subscribe to the stream
let subscription = resourceStream.subscribe(organization => { /* ... */ });
// You should cancel the subscription when you are not interested in the changes any more
subscription.unsubscribe();

SDK will automatically handle real-time channel listening under-the-hood. The client monitors changes to the resource as long as the user of SDK is being subscribed to a resource stream. Therefore, you should unsubscribe when you do not need it any more, in order to prevent unnecessary network traffic.

Observe resources of the authenticated user

// Observe the details of the current user's organization
giosg.api.auth()
    .switchMap(auth => giosg.api.streamResource('/api/v5/orgs/' + auth.organization_id))
    .subscribe(organization => {
        console.log("My organization's name is " + organization.name);
    })
;
// Observe the details of the current user
giosg.api.auth()
    .switchMap(auth => giosg.api.streamResource('/api/v5/orgs/' + auth.organization_id + '/users/' + auth.user_id))
    .subscribe(user => {
        console.log("My name is " + user.full_name);
    })
;

In many cases you may want to use the information of the authenticated user to determine which resources are observed. A common recipe is to use the observable returned by the auth method and Observable.switchMap.

Load resource without observing changes

// Start listening changes to a specific resource
giosg.api.getResource('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b')
    .subscribe(organization => {
        // Emits the resource's latest state and then completes.
        // Does not emit any further changes to the resource.
    }, error => {
        // Failed to load the resource.
    })
;

In some cases you may be interested in just the current state of the resource but not any future changes. You can do this by calling getResource method. This just makes a GET request, without listening real-time changes.

This is similar than calling Observable.first method of the Observable returned by streamResource, but it is more efficient, as it does not use real-time socket connection at all.

In this case, the subscription does not need to be manually unsubscribed, unless you want to abort the request.

Create a new resource

// Create a new resource by posting to a collection
let userData = {
    first_name: "John",
    last_name: "Smith",
    /* etc... */
};
giosg.api.postResource('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users', userData)
    .subscribe(createdUser => {
        // Emits the resource when created successfully. It then completes.
    }, error => {
        // The creation failed!
    })
;

You can get an observable for creating new resource by calling postResource method. By subscribing to it, the resource will be POSTed to the collection. The Observable emits exactly one value: the created resource object. It then completes. In other words, this does not subscribe to any future changes of the resource.

If the creation fails, the observable results in an error.

NOTE: The HTTP request starts only after the observable is actually subscribed. This is because of the anatomy of an observable. In other words, to create a resource, even if you are not interested in the results, you need to call sdk.postResource(...).subscribe();.

Also, by default it makes a new request for each subscriber. If this behavior is not desired, you can multicast the observable, e.g by calling Observable.share.

Update a resource

// Update a new resource by putting
let updatedUserData = {
    first_name: "John",
    last_name: "Doe",
    /* etc... */
};
giosg.api.putResource('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users/6437bd00-5c92-4310-b4b6-1cedb35aa3c9', updatedUserData)
    .subscribe(updatedUser => {
        // Emits the resource when updated successfully. It then completes.
    }, error => {
        // The update failed!
    })
;

You can update an existing resource by calling putResource for a full update or patchResource for a partial update. Similar to postResource, this only emits the updated resource and then completes.

NOTE: As with postResource, these observables needs to be subscribed in order to start the HTTP request, and each subscription results in a new request. See the notes above.

Destroy a resource

// Destroy the resource
giosg.api.deleteResource('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users/6437bd00-5c92-4310-b4b6-1cedb35aa3c9')
    .subscribe(() => {
        // Destroyed successfully!
    }, error => {
        // The destroying failed!
    })
;

You can destroy an existing resource by calling deleteResource for a resource endpoint. Unlike other methods, this only emits a single undefined value when successful. It does not emit any changes (because the resource does not exist any more).

NOTE: As with postResource, this observable needs to be subscribed in order to start the HTTP request, and each subscription results in a new request. See the notes above.

Collections

Observe collection changes

// Start listening changes to the collection
giosg.api.streamCollectionArray('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users')
    .subscribe(users => {
        // Emits the array of ALL the resources in the collection, and then
        // all the changed arrays.
    })
;

The simplest way to observe a collection of resources is to stream arrays of resources.

However, you should only use streamCollectionArray method if you know that your collection is relatively small by its size. This is because all the pagination chunks needs to be loaded from the server before the complete array can be built.

Observe collection resource streams

// Start listening changes to the collection
giosg.api.streamCollection('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users')
    .subscribe(userStream => {
        // Emits an Observable for the users in the collection, according to their current
        // state in the collection. If the contents of the collection is changed, then
        // another Observable is emitted.
    })
;

For large arrays, it is strongly recommended to use lower-level streamCollection method instead. Instead of arrays, it emits higher-order observables, that is, “observables of observables”. The emitted “inner” observables emits all the resources in the collection, in order.

// Observe the first 10 online users from the users collection
giosg.api.streamCollection('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users')
    .switchMap(userStream => {
        // Take the 10 first resources matching the giving criteria, ignoring the rest
        return userStream
            // Include only if the user is online
            .filter(user => user.is_online)
            // Only max. 10 users.
            // SDK only loads the minimum number of required page chunks from the server.
            .take(10)
            // Emit as an array
            .toArray()
        ;
    })
    .subscribe(firstUsers => {
        // Emits the first 10 online users users as an array, and then
        // a new array whenever the collection changes.
    })
;

The collection pagination chunks are loaded lazily on-demand. That is, the pages are only actually loaded from the server if there are any subscribers interested in their contents! For example, you can use Observable.take to take only the given number of first resources from the collection. The latter pages are not loaded from the server at all, making the operation fast even for very large collections.

Please be careful when working with higher-order observables. It is likely that the underlying collection sometimes changes before a “inner” Observable is completed, making it obsolete. For example, a resource is added to the collection before all the page chunks are loaded from the server. Luckily, Observable has handly methods to manage inner observables! For example, you can use Observable.switchMap which is useful to only use the latest emitted inner stream of resources.

Stop observing collection changes

// Start listening changes to the collection
let collectionStream = giosg.api.streamCollection('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users');
// Subscribe to the stream
let subscription = collectionStream.subscribe(userStream => { /* ... */ });
// You should cancel the subscription when you are not interested in the changes any more
subscription.unsubscribe();

As with any stream returned by the SDK, you should unsubscribe your subscription when you are not interest in the changes any more!

Load a collection without observing changes

// Returns an observable for the current contents of the collection
giosg.api.getCollection('/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users')
    .subscribe(user => {
        // Calls this for EACH RESOURCE in the collection and then completes!
    }, error => {
        // Loading one of the collection page loads failed!
    })
;

Sometimes you just want to get all the resources in the collection without observing the changes to the content. In this case you can use getCollection method that just retrieves the current resources in the collection as a single observable. It emits the items until the end of the collection is reached, and then completes.

The main difference to earlier methods is that the observable emits single resources, not the whole collection. This is roughly equivalent to: sdk.streamCollection(...).first().mergeAll() but is more efficient, because it does not use the real-time socket connection at all.

Ordering collections

// Observe the collection in a specific order
let collectionStream = giosg.api.streamCollection(
        '/api/v5/orgs/c0c329ce-bd7f-41e3-b79b-af2f7f9f334b/users',
        {ordering: '-created_at'}
    )
    // Convert to arrays of max. 10 most recently created users
    .switchMap(userStream => userStream.take(10).toArray())
    .subscribe(recentlyCreatedUsers => {
        // Emits max. 10 most recently created users as an array,
        // and then a new array whenever a new user is created!
    })
;

The streamCollection, streamCollectionArray and getCollection methods accepts additional options. You can use the ordering option to define the order of the resources in the collection. The option must be supported by the HTTP endpoint.

As with the HTTP endpoint, you may use the - prefix to reverse the order. You can also separate secondary sorting criterias with commas (,).