# Upsert should always return the uid

**URL:** <https://discuss.dgraph.io/t/upsert-should-always-return-the-uid/8182>\
**Category:** Dgraph Clients\
**Tags:** untagged, dgraph-js\
**Created:** [September 13, 2019, 9:31am UTC](https://discuss.dgraph.io/t/upsert-should-always-return-the-uid/8182 "2019-09-13T09:31:24Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![diggy](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/diggy/32/3666_2.png) [@diggy](https://discuss.dgraph.io/u/diggy)\
**Post date:** [September 13, 2019, 9:31am UTC](https://discuss.dgraph.io/t/upsert-should-always-return-the-uid/8182/1 "2019-09-13T09:31:24Z")

</div>

**Moved from GitHub [dgraph-js/73](https://github.com/dgraph-io/dgraph-js/issues/73)**

_Posted by_ [pepoospina](https://github.com/pepoospina):

## Experience Report

### What you wanted to do

I am using an upsert operation as described in [dgraph-js](https://github.com/dgraph-io/dgraph-js#running-an-upsert-query--mutation) to **get or create** a new node with a given external id called `did` and return its `uid`.

### What you actually did

This is my code. It works the first time the node with the external id `did` does not exist. But it fails if it does exist.

```auto
    const mu = new dgraph.Mutation();
    const req = new dgraph.Request();

    let query = `profile as var(func: eq(did, "${did}"))`;
  
    req.setQuery(`query{${query}}`);

    let nquads = `uid(profile) <did> "${did}" .`;
    nquads = nquads.concat(`\nuid(profile) <dgraph.type> "${PROFILE_SCHEMA_NAME}" .`);

    mu.setSetNquads(nquads);
    req.setMutationsList([mu]);
    req.setCommitNow(true);

    let response = await this.client.newTxn().doRequest(req);
    let uid = response.getUidsMap().get("uid(profile)")
    return uid;

```

### Why that wasn’t great, with examples

I will have to add new logic to my function to consider the case in which the result is empty and run a new query to get the `uid` of that `did`.

I don’t like how that `if` looks inside my function. Is that a code smell? Should the upsert return the `uid` even if it did not create it?

This is my updated function

```auto
    const mu = new dgraph.Mutation();
    const req = new dgraph.Request();

    let query = `profile as var(func: eq(did, "${did}"))`;
  
    req.setQuery(`query{${query}}`);

    let nquads = `uid(profile) <did> "${did}" .`;
    nquads = nquads.concat(`\nuid(profile) <dgraph.type> "${PROFILE_SCHEMA_NAME}" .`);

    mu.setSetNquads(nquads);
    req.setMutationsList([mu]);
    req.setCommitNow(true);

    let response = await this.client.newTxn().doRequest(req);
    let uid = response.getUidsMap().get("uid(profile)")

    if (!uid) {
        // it already existed. query for it.
        const didQuery = `
        query {
            profile(func: eq(did, "${did}")) {
              uid
            }
        }
        `;
        let result = await this.client.newTxn().query(didQuery);
        let profile = result.getJson().profile[0];
        uid = profile.uid;
    }

    return uid;

```

### Any external references to support your case

---

<div class="post-metadata">

**Author:** ![diggy](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/diggy/32/3666_2.png) [@diggy](https://discuss.dgraph.io/u/diggy)\
**Post date:** [September 13, 2019, 5:50pm UTC](https://discuss.dgraph.io/t/upsert-should-always-return-the-uid/8182/2 "2019-09-13T17:50:50Z")

</div>

[campoy](https://github.com/campoy) _commented_ :

Thanks for your report, @pepoospina

Moving this issue to the dgraphjs repository.

---

<div class="post-metadata">

**Author:** ![diggy](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/diggy/32/3666_2.png) [@diggy](https://discuss.dgraph.io/u/diggy)\
**Post date:** [September 14, 2019, 3:34pm UTC](https://discuss.dgraph.io/t/upsert-should-always-return-the-uid/8182/3 "2019-09-14T15:34:07Z")

</div>

[pepoospina](https://github.com/pepoospina) _commented_ :

@campoy I am not sure is an issue of dgraph-js. The standard dgraph `upsert` operation will not return the `uid` if the entry already existed.

---

<div class="post-metadata">

**Author:** ![diggy](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/diggy/32/3666_2.png) [@diggy](https://discuss.dgraph.io/u/diggy)\
**Post date:** [December 10, 2019, 10:27am UTC](https://discuss.dgraph.io/t/upsert-should-always-return-the-uid/8182/4 "2019-12-10T10:27:29Z")

</div>

[prashant-shahi](https://github.com/prashant-shahi) _commented_ :

@pepoospina We can retrieve UID of the existing node by including `uid` to the query part of the upsert operation.

```auto
const mu = new dgraph.Mutation();
const req = new dgraph.Request();

let query = `profile as all(func: eq(did, "${did}")) {
  uid
  did
}`;

req.setQuery(`query{${query}}`);

let nquads = `uid(profile) <did> "${did}" .`;
nquads = nquads.concat(`\nuid(profile) <dgraph.type> "${PROFILE_SCHEMA_NAME}" .`);

mu.setSetNquads(nquads);
req.setMutationsList([mu]);
req.setCommitNow(true);

let response = await dgraphClient.newTxn().doRequest(req);
let uid = response.getUidsMap().get("uid(profile)");
if (uid === undefined) {
  uid = response.getJson().all[0].uid;
}
console.log(uid);

```

---

<div class="post-metadata">

**Author:** ![diggy](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/diggy/32/3666_2.png) [@diggy](https://discuss.dgraph.io/u/diggy)\
**Post date:** [July 11, 2020, 4:19am UTC](https://discuss.dgraph.io/t/upsert-should-always-return-the-uid/8182/5 "2020-07-11T04:19:44Z")

</div>


