Json string array to object in Vuex - json

In my states I have categories. In the categories array every each category have a settings column where I have saved json array string.
My question it is,how can I turn my string to object by filtering the response ?
My response:
[{"id":4,"name":"Vehicles","slug":"vehicles","settings":"[{"edit":true,"searchable":true}]","created_at":"2019-01-26 16:37:36","updated_at":"2019-01-26 16:37:36"},
This is my loading action for the categories:
const loadCategories = async ({ commit }, payload) => {
commit('SET_LOADING', true);
try {
const response = await axios.get(`admin/store/categories?page=${payload.page}`);
const checkErrors = checkResponse(response);
if (checkErrors) {
commit('SET_DIALOG_MESSAGE', checkErrors.message, { root: true });
} else {
commit('SET_STORE_CATEGORIES', response.data);
}
} catch (e) {
commit('SET_DIALOG_MESSAGE', 'errors.generic_error', { root: true });
} finally {
commit('SET_LOADING', false);
}
};
This is my SET_STORE_CATEGORIES:
const SET_STORE_CATEGORIES = (state, payload) => {
state.categories=payload.data;
state.pagination = {
currentPage: payload.current_page,
perPage: payload.per_page,
totalCategories: payload.total,
totalPages: payload.last_page,
};
};
Here I would like to add to modify the value ,to turn the string to object.
Had to add:
let parsed=[];
parsed=response.data.data.map((item)=>{
console.log(item);
let tmp=item;
tmp.settings=JSON.parse(item.settings);
return tmp;
});
response.data.data=parsed;
commit('SET_STORE_CATEGORIES', response.data);

You could map your response data as follows by parsing that string to an object :
let parsed=[];
parsed=response.data.map((item)=>{
let tmp=item;
tmp.settings=JSON.parse(item.settings);
return tmp;
});
commit('SET_STORE_CATEGORIES', parsed);

Related

ipfs.add() returns Object [AsyncGenerator] {}

I am unable to figure out what mistake i have done in the code
Whenever i am calling api, ipfs.add('hello') returns [object AsyncGenerator]
https://gateway.ipfs.io/ipfs/[object AsyncGenerator]
const addFile = async () => {
const Added = await ipfs.add('hello');
return Added;
}
const fileHash = await addFile();
return fileHash;
You can iterate over the result of .add() like so:
for await (const item of Added) {
console.log('item', item)
}
item { path: 'QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX',
cid: CID(QmWfVY9y3xjsixTgbd9AorQxH7VtMpzfx2HaWtsoUYecaX), size: 13 }

change value from of a specific item on button click

As I asked yesterday in my first post, I have a json file that looks like this:
groups:{[
{
title:Animal
shown:false
data:[{....}]
}
........
.....
]}
I want to change the shown value on a button click. The closest thing I found to my problem was this part of code:
newState = this.state.groups.map((val,i) => {
if(index === i){
return { ...val, shown: false};
}
return val;
})
this.setState({
groups: newState,
})
However, it doesn't seem to work, logging on console doesn't show any differences before and after the button press. I'm rather new to this so do you mind to help me understand what i did bad?
edit: I tried changing from index to a simple number to see if that was the problem, but still the same problem.
A JSON object is collection of Key Value pairs. i.e.
let FullName = {
firstName: "Stack",
lastName: "OverFlow"
}
In FullName Object Keys are firstName and lastName and corresponding values are "Stack" and "Overflow".
The groups Object that you have defined is missing the key Property.
Coming to Your problem:
Case1: If groups Object is an Array of Objects then:
var groups = [
{
title: 'Animal',
shown: false,
data: [{}]
},
{
title: 'Birds',
shown: false,
data: [{}]
}
]
/* Upadate By Index value */
/*
var index = 1;
let updatedGroup = groups.map((val,i) => {
if(index === i){
return { ...val, shown: true};
}
return val;
})
*/
/* Upadate By title */
/* let title = "Animal";
let updatedGroup = groups.map((val,i) => {
if(val.title === title){
return { ...val, shown: true};
}
return val;
}) */
// To toggle the shown Value Each Time
let title = "Animal";
let updatedGroup = groups.map((val,i) => {
if(val.title === title){
return { ...val, shown: !val.shown};
}
return val;
})
console.log("updatedGroup", updatedGroup);
Case2: If groups Object is Object of Objects then
var groups = {
group1: {
title: 'Animal',
shown: false,
data: [{}]
},
group2: {
title: 'Birds',
shown: false,
data: [{}]
}
}
let index = 1;
let updatedGroup = Object.values(groups).map((val, i)=>{
if(index === i){
return { ...val, shown: true};
}
return val;
})
console.log("updatedGroup",updatedGroup)

Why isn't my function returning the proper JSON data and how can I access it?

I'm running services to retrieve data from an API. Here is one of the services:
robotSummary(core_id, channel_name){
const params = new HttpParams()
var new_headers = {
'access-token': ' '
};
this.access_token = sessionStorage.getItem('access-token');
new_headers['access-token'] = this.access_token;
const myObject: any = {core_id : core_id, channel_name: channel_name};
const httpParams: HttpParamsOptions = { fromObject: myObject } as HttpParamsOptions;
const options = { params: new HttpParams(httpParams), headers: new_headers };
return this.http.get(this.baseURL + 'web_app/robot_summary/',options)
.subscribe(
res => console.log(res),
)
}
}
The data shows up properly on the console, but I still can't access the individual keys:
Here is how I call it:
ngOnInit(): void{
this.login.getData(this.username, this.password).subscribe((data) => {
this.robotSummaryData = this.getRobotSummary.robotSummary(this.core_id, this.channel_name);
console.log("robosummary"+ this.robotSummaryData)
});
}
When I call this function and assign it to a variable, it shows up on console as [object Object]. When I tried to use JSON.parse, it throws the error: type subscription is not assignable to parameter string. How can I access the data? I want to take the JSON object and save it as an Object with appropriate attributes. Thanks!
Do not subscribe inside your service, do subscribe in your component, change your service as follows,
robotSummary(core_id, channel_name){
const params = new HttpParams()
var new_headers = {
'access-token': ' '
};
this.access_token = sessionStorage.getItem('access-token');
new_headers['access-token'] = this.access_token; const myObject: any = { core_id: core_id, channel_name: channel_name };
const httpParams: HttpParamsOptions = { fromObject: myObject } as HttpParamsOptions;
const options = { params: new HttpParams(httpParams), headers: new_headers };
return this.http.get(this.baseURL + 'web_app/robot_summary/', options)
.map((response: Response) => response);
}
and then in your component,
ngOnInit(){
this.api..getRobotSummary.robotSummary(this.core_id, this.channel_name).subscribe((data) => {
this.data = data;
console.log(this.data);
});
}

GraphQL/GraphCool Why do coordinates don't work with FLOAT?

I'm currently working on GraphQL/GraphCool wrapping a RestAPI, but when I write my resolver with Float in order to extract latitude and longitude as floats I get the following error:
"code": 5004,
"message": "Returned JSON Object does not match the GraphQL type. The field 'latitud' should be of type Float \n\n Json:
{\n \"id\": \"6115\",\n \"nombre\": \"ABARROTES LA SOLEDAD\",\n \"latitud\": \"21.85779823\",\n \"longitud\": \"-102.28161261\"\n}\n\n"
if I use String there is no problem!
RESOLVER SDL
type AbarrotesPayload {
id: ID!
nombre: String!
latitud: Float!
longitud: Float!
}
extend type Query {
feed(distancia: Int!): [AbarrotesPayload!]!
}
RESOLVER FUNCTION
"use strict";
const fetch = require("node-fetch");
const API_TOKEN = "d3bfd48a-bced-4a58-a58b-4094da934cf1";
module.exports = event => {
const distancia = event.data.distancia;
return fetch(getRestEndpoint(distancia, API_TOKEN))
.then(response => response.json())
.then(data => {
const abarrotes = [];
for (let item in data) {
abarrotes.push({
id: data[item].Id,
nombre: data[item].Nombre,
latitud: data[item].Latitud,
longitud: data[item].Longitud
});
}
console.log(abarrotes);
return { data: abarrotes };
});
};
function getRestEndpoint(query) {
return `http://www3.inegi.org.mx/sistemas/api/denue/v1/consulta/buscar/abarrotes/21.85717833,-102.28487238/${query}/${API_TOKEN}`;
}
And my Query is the following:
query {
feed(distancia: 400) {
id
nombre
latitud
longitud
}
}
By the way, im working on the graph.cool platform!
This had nothing to do with GraphQL/GraphCool, I just needed to parseFloat() the values which I'm receiving as a string, and then push it to the array.
latitud: parseFloat(data[item].Latitud),
longitud: parseFloat(data[item].Longitud)

Transform Request to Autoquery friendly

We are working with a 3rd party grid (telerik kendo) that has paging/sorting/filtering built in. It will send the requests in a certain way when making the GET call and I'm trying to determine if there is a way to translate these requests to AutoQuery friendly requests.
Query string params
Sort Pattern:
sort[{0}][field] and sort[{0}][dir]
Filtering:
filter[filters][{0}][field]
filter[filters][{0}][operator]
filter[filters][{0}][value]
So this which is populated in the querystring:
filter[filters][0][field]
filter[filters][0][operator]
filter[filters][0][value]
would need to be translated to.
FieldName=1 // filter[filters][0][field]+filter[filters][0][operator]+filter[filters][0][value] in a nutshell (not exactly true)
Should I manipulate the querystring object in a plugin by removing the filters (or just adding the ones I need) ? Is there a better option here?
I'm not sure there is a clean way to do this on the kendo side either.
I will explain the two routes I'm going down, I hope to see a better answer.
First, I tried to modify the querystring in a request filter, but could not. I ended up having to run the autoqueries manually by getting the params and modifying them before calling AutoQuery.Execute. Something like this:
var requestparams = Request.ToAutoQueryParams();
var q = AutoQueryDb.CreateQuery(requestobject, requestparams);
AutoQueryDb.Execute(requestobject, q);
I wish there was a more global way to do this. The extension method just loops over all the querystring params and adds the ones that I need.
After doing the above work, I wasn't very happy with the result so I investigated doing it differently and ended up with the following:
Register the Kendo grid filter operations to their equivalent Service Stack auto query ones:
var aq = new AutoQueryFeature { MaxLimit = 100, EnableAutoQueryViewer=true };
aq.ImplicitConventions.Add("%neq", aq.ImplicitConventions["%NotEqualTo"]);
aq.ImplicitConventions.Add("%eq", "{Field} = {Value}");
Next, on the grid's read operation, we need to reformat the the querystring:
read: {
url: "/api/stuff?format=json&isGrid=true",
data: function (options) {
if (options.sort && options.sort.length > 0) {
options.OrderBy = (options.sort[0].dir == "desc" ? "-" : "") + options.sort[0].field;
}
if (options.filter && options.filter.filters.length > 0) {
for (var i = 0; i < options.filter.filters.length; i++) {
var f = options.filter.filters[i];
console.log(f);
options[f.field + f.operator] = f.value;
}
}
}
Now, the grid will send the operations in a Autoquery friendly manner.
I created an AutoQueryDataSource ts class that you may or may not find useful.
It's usage is along the lines of:
this.gridDataSource = AutoQueryKendoDataSource.getDefaultInstance<dtos.QueryDbSubclass, dtos.ListDefinition>('/api/autoQueryRoute', { orderByDesc: 'createdOn' });
export default class AutoQueryKendoDataSource<queryT extends dtos.QueryDb_1<T>, T> extends kendo.data.DataSource {
private constructor(options: kendo.data.DataSourceOptions = {}, public route?: string, public request?: queryT) {
super(options)
}
defer: ng.IDeferred<any>;
static exportToExcel(columns: kendo.ui.GridColumn[], dataSource: kendo.data.DataSource, filename: string) {
let rows = [{ cells: columns.map(d => { return { value: d.field }; }) }];
dataSource.fetch(function () {
var data = this.data();
for (var i = 0; i < data.length; i++) {
//push single row for every record
rows.push({
cells: _.map(columns, d => { return { value: data[i][d.field] } })
})
}
var workbook = new kendo.ooxml.Workbook({
sheets: [
{
columns: _.map(columns, d => { return { autoWidth: true } }),
// Title of the sheet
title: filename,
// Rows of the sheet
rows: rows
}
]
});
//save the file as Excel file with extension xlsx
kendo.saveAs({ dataURI: workbook.toDataURL(), fileName: filename });
})
}
static getDefaultInstance<queryT extends dtos.QueryDb_1<T>, T>(route: string, request: queryT, $q?: ng.IQService, model?: any) {
let sortInfo: {
orderBy?: string,
orderByDesc?: string,
skip?: number
} = {
};
let opts = {
transport: {
read: {
url: route,
dataType: 'json',
data: request
},
parameterMap: (data, type) => {
if (type == 'read') {
if (data.sort) {
data.sort.forEach((s: any) => {
if (s.field.indexOf('.') > -1) {
var arr = _.split(s.field, '.')
s.field = arr[arr.length - 1];
}
})
}//for autoquery to work, need only field names not entity names.
sortInfo = {
orderByDesc: _.join(_.map(_.filter(data.sort, (s: any) => s.dir == 'desc'), 'field'), ','),
orderBy: _.join(_.map(_.filter(data.sort, (s: any) => s.dir == 'asc'), 'field'), ','),
skip: 0
}
if (data.page)
sortInfo.skip = (data.page - 1) * data.pageSize,
_.extend(data, request);
//override sorting if done via grid
if (sortInfo.orderByDesc) {
(<any>data).orderByDesc = sortInfo.orderByDesc;
(<any>data).orderBy = null;
}
if (sortInfo.orderBy) {
(<any>data).orderBy = sortInfo.orderBy;
(<any>data).orderByDesc = null;
}
(<any>data).skip = sortInfo.skip;
return data;
}
return data;
},
},
requestStart: (e: kendo.data.DataSourceRequestStartEvent) => {
let ds = <AutoQueryKendoDataSource<queryT, T>>e.sender;
if ($q)
ds.defer = $q.defer();
},
requestEnd: (e: kendo.data.DataSourceRequestEndEvent) => {
new DatesToStringsService().convert(e.response);
let ds = <AutoQueryKendoDataSource<queryT, T>>e.sender;
if (ds.defer)
ds.defer.resolve();
},
schema: {
data: (response: dtos.QueryResponse<T>) => {
return response.results;
},
type: 'json',
total: 'total',
model: model
},
pageSize: request.take || 40,
page: 1,
serverPaging: true,
serverSorting: true
}
let ds = new AutoQueryKendoDataSource<queryT, T>(opts, route, request);
return ds;
}
}