Guide / JavaScript /

Remote procedure calls

When we did a mutation of dataServer on client, the server didn't receive the mutation. That is because is unidiectional dataflow as mentiones before.

But what we can do is define a function on server and call that function from the client.

// server
dataServer.increaseTotalUsers = () => {
    dataServer.totalUsers += 1
}

We just have to call that function on client and we will receive the mutation as usual with dop.observe

// client
const observer = dop.createObserver(mutations => {
    console.log(dataServer.totalUsers)
})
observer.observe(dataServer)

dataServer.increaseTotalUsers()

What about getting values?

// server
dataServer.square = number => number*number

// client
let squareOfFive = await dataServer.square(5) // > 25

Multiple arguments

// server
dataServer.fullName = (name, surname) => `Your full name is ${name} ${surname}`

// client
await dataServer.fullName('John', 'Doe') // > "Your full name is John Doe"

When calling a remote function, the last argument is always a deferred promise with an extra property that identifies the node that is calling the function.

As a promise we can reject it.

// server
dataServer.login = (email, password, ...args) => {
    const req = args[args.length-1]
    const reject = req.reject
    if (email === 'johndoe@mail.com' && password === '1234')
        return true
    else
        return reject('Invalid login')
}

// client
try {
    const isLogged = await dataServer.login('wrong', 'wrong')
}
catch (message_error) {
    console.error(message_error) // > 'Invalid login'
}

Resolving asynchronously

// server
dataServer.login = (email, password, ...args) => {
    const req = args[args.length-1]
    const resolve = req.resolve
    const reject = req.reject
    setTimeout(()=>{
        if (email === 'johndoe@mail.com' && password === '1234')
            resolve(true)
        else
            reject('Invalid login')
    }, 1000)

    // You must return req to make this function asynchronously
    return req
}

Getting the node that is running this function

// server
dataServer.getMyToken = (...args) => {
    const req = args[args.length-1]
    const node = req.node
    return node.token
}

// client
const isLogged = await dataServer.getMyToken() // > a54a6843-08a9-4332-a365-0c86aa4fe0b5

When calling a remote function always return a Promise. Instead of await we can resolve the previous example as normal promises.

// client
dataServer.login('johndoe@mail.com', '1234')
    .then(isLogged => console.log(isLogged))
    .catch(message_error => console.error(message_error))

Next step

Using multiple transports