0

I have this attributes data

        for(var k = 0;k<this.form.fields.length;k++)
                    {
       
                        this.dynamic_fields.push({attribute_id:attributes[k].id,value: attributes[k].value})
                      
                    }

this.$router.push({ 
    path: '/api/search-temp',
    query:{
        attributes: this.encodedAttributes()                     
    }
});

    encodedAttributes() {
    const queryAttributes =this.dynamic_fields;
    if (queryAttributes) {
        return typeof queryAttributes !== "string"
            ? btoa(JSON.stringify(queryAttributes))
            : queryAttributes;
    }
    return "";
},

I have a attribute id and an attribute value so i want to pass this id and value to url so that i cab loop in my controller attributes array and get id and value :

localhost:8000..?attributes[]['attribute_id_1']=attributevalue1&attributes[]['attribute_id_2']=attributevalue2...

I'm redirecting like this :

 this.$router.push({ path: '/search-list',query:
                    {

                     
                    }

Issue is i want to pass this multidimentional array to url, anyother workaround for this is also highly appreciated

2 Answers 2

1

What you may try is to json stringify and encode the object before passing it to the $route query

function encodedAttributes() {
    const queryAttributes = this.$route.query.attributes;
    if (queryAttributes) {
        return typeof queryAttributes !== "string"
            ? btoa(JSON.stringify(this.$route.query.attributes))
            : queryAttributes;
    }
    return "";
}

function decodedAttributes() {
    const attributes = this.$route.query.attributes;
    if (typeof attributes === "string" && attributes.length) {
        return JSON.parse(atob(attributes));
    } else {
        return attributes;
    }        
}

And pass as query parameters to the route

this.$router.push({ 
    path: '/search-list',
    query:{
        attributes: this.encodedAttributes()                     
    }

Then in the Controller you can decode the attributes value from request data to get the associated array

class MyController extends Controller
{
    public function index(Request $request)
    {
        $request->attributes = is_array(
            $requestAttributes = json_decode(base64_decode($request->attributes), true)
        ) 
            ? $requestAttributes 
            : [];
        
        //Do other processing as needed
    }
}

Had used something similar in one of my projects can't get my hands on the code right now.

Probably you can use function to escape unicode characters in the encodedAttributes as well as decodedAttributes if need be

function escapeUnicode(str){
    return str.replace(/[^\0-~]/g, c => '\\u' + ('000' + c.charCodeAt().toString(16)).slice(-4))
}

function encodedAttributes() {
    const queryAttributes = this.$route.query.attributes;
    if (queryAttributes) {
        return typeof queryAttributes !== "string"
            ? btoa(escapeUnicode(JSON.stringify(this.$route.query.attributes)))
            : queryAttributes;
    }
    return "";
}


function decodedAttributes() {
    const attributes = this.$route.query.attributes;
    if (typeof attributes === "string" && attributes.length) {
        return JSON.parse(atob(escapeUnicode(attributes)));
    } else {
        return attributes;
    }        
}
9
  • Thanks, can u also specify in the answer how and in which format i will pass data to this.$route.query.attributes Commented Nov 24, 2020 at 5:56
  • That is what I have shown in the answer attributes can be a plain javascript object in vue component. What we are doing is converting the attributes object to JSON string and then encoding it before pushing it to this.$route
    – Donkarnash
    Commented Nov 24, 2020 at 7:02
  • You can initialise attributes in the data function of the Vue component or a method. Then you can modify the signature of encodedAttributes as function encodedAttributes(attributes = null){ const queryAttributes = attributes ? attributes || this.$route.query.attributes; //rest of the function declaration }
    – Donkarnash
    Commented Nov 24, 2020 at 8:18
  • I have tried but getting url like this attributes=W3siYXR0cmlidXRlX2lkIjozLCJhdHRyaWJ1dGVfbmFtZSI6IlNlYXRzIiwidmFsdWUiOiI2In0seyJhdHRyaWJ1dGVfaWQiOjQsImF0dHJpYnV0ZV9uYW1lIjoiQ29sb3IiLCJ2YWx1ZSI6Ik90aGVyIn1d, and not getting attribute, i have edited my code in my question can u please check what's the issue in the code Commented Nov 24, 2020 at 15:33
  • Yes it's an encoded string and you can easily decode it in your Laravel Controller. So what is the issue - that url has some nasty looking encoded string. It doesn't matter, in fact it's probably more preferable from security point of view
    – Donkarnash
    Commented Nov 24, 2020 at 15:51
0

You're trying to set a nested object to the query params, it's not possible... your route's query object must be a flat object.

Summarizing the only way for you to have something like this:

?attributes[]['attribute_id_1']=attributevalue1&attributes[]['attribute_id_2']=attributevalue2

Would be from a query object like this:

query: {
  "attributes[]['attribute_id_1']": 'attributevalue1',
  "attributes[]['attribute_id_2']": 'attributevalue2',
}

You should flatten this multidimensional array into an simples object and use it as your query object.

Here is an example...
From this:

const multiDimArr = [
  ['attribute_1', 'value1'],
  ['attribute_2', 'value2']
];

Into:

const myObject = {
  attribute_1: 'value1',
  attribute_2: 'value2'
}

A way to do so would be:

const multiDimArr = [
  ['attribute_1', 'value1'],
  ['attribute_2', 'value2']
];

const myObject = {};

multiDimArr.forEach(arr => {
  myObject[arr[0]] = arr[1];
});

And then use the object as the query object, so your url will look like this:

?attribute_1=value1&attribute_2=value2
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.